Возвращение данных в реактивную форму в Angular 7

Я поставил перед собой задачу войти в систему, получить существующие данные пользователя, а затем предоставить пользователю возможность редактировать их. У меня есть реактивная форма Angular 7, например:

userdetails.page.ts

    constructor(private formBuilder: FormBuilder,
    private currentuser: UserService,
    private router: Router ) {

     }

     ngOnInit() {
    // first we need to make sure the current user data is up to date.
      this.currentuser.getUserServer();
      //
        console.info('currentUser = ' + this.currentuser.data);


      this.userDetailsForm = this.formBuilder.group({
        id: [this.currentuser.data.Id],
        email: [this.currentuser.data.Email],  // [Validators.required, Validators.email]],
        username: [this.currentuser.data.UserName],
        dateofbirth: [this.currentuser.data.DateOfBirth],
        title: [this.currentuser.data.Title],
        firstname: [this.currentuser.data.FirstName],
        middlename: [this.currentuser.data.MiddleName],
        lastname: [this.currentuser.data.LastName],
        displayname: [this.currentuser.data.DisplayName],
        fullname: [this.currentuser.data.FullName],
        detailscomplete: [this.currentuser.data.Id],
        password: [this.currentuser.data.Password], // [Validators.required, Validators.minLength(6)]]
      });

  }

Я пытаюсь разделить вещи, поэтому у меня есть пользовательский сервис и сервис API. (Но я не уверен, что служба API строго необходима - или она должна быть просто частью вызова пользовательской службы?) Служба API (используемая функция):

API.service.ts

  Get(endpoint: string) {
        const fullurl = this.ServerUrl + endpoint;
        return this.http.get(fullurl, {
          headers: {'Content-Type': 'application/json'}
        });

  }

Что, как я понимаю, возвращает наблюдаемое, и именно здесь я немного застреваю. Объект JSON с сервера также содержит некоторые нерелевантные объекты, а также те, которые мне нужны, поэтому я пытаюсь получить только те элементы, которые мне нужны. Средняя функция имеет следующее:

user.service.ts

public data:  UserData;

getUserServer() {
  this.api.Get(this.api.GetUserDetailsEndPoint).subscribe(res => {
    console.info('Id from server = ' + res['Id']);
    this.data = {
    Id:           res['Id'],
    Email:        res['Email'],
    UserName:     res['UserName'],
    DateOfBirth:  res['DateOfBirth'],
    Title:        res['title'],
    FirstName:    res['FirstName'],
    MiddleName:   res['MddleName'],
    LastName:     res['LastName'],
    DisplayName:  res['DisplayName'],
    FullName:     res['FullName'],
    DetailsComplete: res['DetailsComplete'],
    Password:     res['Password']
    };
    console.info('This Data.Id = ' + this.data.Id)
  });
}

Это работает до момента получения данных, и регистрация идентификатора представляет правильную информацию, и другие тоже есть. (Последняя строка выше.) Однако я чувствую, что мне нужно превратить this.data в наблюдаемую, чтобы вернуться к форме, где я, вероятно, должен подписаться на нее.

Я попытался определить это как observable<UserData>, а также observable<IUserData> (это интерфейс, а не класс), но это нарушает назначение элементов. Я чувствую, что я довольно близок, но упускаю что-то основное.

Это правильный подход? Как я могу получить возвращенные данные на самом деле в форме? Затем, я думаю, возвращение на сервер будет происходить в том же духе.

Услуга не должна быть подписана. И он не должен хранить никаких данных. Он должен быть вернуть наблюдаемым. Затем компонент может вызвать службу, получить обратно наблюдаемое, подписаться на него и внутри обратного вызова, переданного для подписки, получить доступ к данным и заполнить форму. Вы должны понимать, что весь смысл наблюдаемых объектов заключается в том, чтобы иметь возможность получать уведомления асинхронно спустя долгое время после того, как вы вызвали службу, когда ответ http, наконец, доступен.

JB Nizet 06.04.2019 16:17

Да, я понимаю, это то, с чем я борюсь, наверное. Не хранить данные в сервисе — хороший совет, и я собираюсь попробовать предложение ngFelixl. Спасибо...

Brett JB 06.04.2019 17:14
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
2
2
599
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Причина, по которой ваш код не работает, заключается в том, что он асинхронный. Данные не заносятся в журнал, поскольку журнал выполняется до поступления данных.

Я предлагаю сначала создать пустую форму, убедитесь, что свойства точно соответствуют свойствам в ваших данных. Ваш подход правильный. В вашем user.service.ts переключите код на

getUserServer(): Observable<UserData> {
  return this.http.get<UserData>(`pathToEndpoint`);
}

В вашем userdetails.page.ts

constructor(private userService: UserService, ...) {}

ngOnInit() {
  this.userForm = this.formBuilder.group({
    Id: [],
    ...
  });

  this.userService.getUserServer().subscribe(user => this.userForm.patchValue(user.data));
}

Функция patchValue, предоставляемая формой, исправляет все ключевые совпадения между вашими данными и формой. Он игнорирует свойства, недоступные в форме, и наоборот. Вам следует подумать о переименовании всех свойств в lowerCamelCase.

Совет, когда вы продолжите работу с RxJS: вы почти везде прочтете, что вам нужно отписаться от наблюдаемых, если вы подписались на них. Но это только половина правды. Если вы уверены, что наблюдаемая будет завершена, вам не нужно отписываться. HttpClient.get предназначен для завершения после того, как он выдал свое первое значение, или для выдачи ошибки. Поэтому вам не нужно отписываться от него. Но будьте осторожны, когда используете подписки. Вы поймете яснее, если прочитаете об операторах типа брать.

Спасибо, я попробую... значит, вы говорите, что мне не следует использовать службу API, я пытался сохранить ее в чистоте, имея все конечные точки URL и доступ в одном месте.?

Brett JB 06.04.2019 17:11

Лучше всего хранить конечные точки URL в виде строки в файлах environments в разделе src/environments/environment(.prod).ts. Это также упрощает тестирование вашего приложения с поддельным бэкэндом. Затем вы можете импортировать среду с помощью import {environment} from './pathTo/environment.ts'; и получить доступ к свойствам, например. environment.apiEndpoint.

Felix Lemke 06.04.2019 17:12

Может быть, не «apiEndpoint», а «apiUrl», а затем используйте this.http.get<UserData>(environment.apiUrl + '/entity').

Felix Lemke 06.04.2019 17:21

Спасибо, ngfelixl, пометка как ответ, это ОЧЕНЬ помогло... Я бы все же спросил, что бы я тогда использовал для обработки данных в пути... например. Я замечаю, что дата не прошла, потому что значение в json, например. «1958-05-17T00:00:00», а требуемый формат — «гггг-ММ-дд». ? С уважением Бретт

Brett JB 06.04.2019 18:13

@BrettJB, ты бы ничего не использовал. Отображение дат в определенном формате не является обязанностью службы. Это ответственность взгляда. Используйте канал даты в представлении. Оставьте данные как должно быть.

JB Nizet 06.04.2019 18:35

Другие вопросы по теме