Наблюдаемый не вызывается при использовании asObservable () с Subject in Angular? - PullRequest
0 голосов
/ 30 июня 2019

У меня есть компонент, который отображает форму для пользователя.После того, как пользователь выберет кнопку отправки в этой форме, я хотел бы вызвать запрос http.post к бэкэнду

. Я хочу использовать BehaviorSubject и .asObservable () с помощью he |асинхронный канал для достижения этой цели.

В моем файле PreOrderComponenT компонент ts настроено следующее:

preOrder$ = this.preOrderService.preOrder$;

onSubmit() {
    console.log(this.preOrderForm);
    const preOrderForm: PreOrderForm = {
      firstName: this.preOrderForm.value.firstName,
      lastName: this.preOrderForm.value.lastName,
      phoneNumber: this.preOrderForm.value.phoneNumber,
      email: this.preOrderForm.value.email,
      orderDetails: {
        quantity: this.preOrderForm.value.orderDetails.quantity,
        size: this.preOrderForm.value.orderDetails.size,
        gearItemId: this.gearItem.id
      },
      contactPreference: {
        cellOrEmail: this.preOrderForm.value.contactPreference.cellOrEmail
      }
    };
    this.preOrderService.preOrderGearItem(preOrderForm);
  }

В PreOrderComponentУ меня есть следующее в шаблоне:

<ng-container *ngIf="preOrderService.preOrder$ | async as preOrderItem">
  <div> TEST </div>
</ng-container>

В PreOrderService у меня есть следующее:

    preOrderAction: BehaviorSubject<PreOrderForm> = new BehaviorSubject<
        PreOrderForm
      >(null);

      preOrder$ = this.preOrderAction.asObservable().pipe(
        switchMap((preOrderForm: PreOrderForm) => {
          console.log("PreORderTriggered");
          return this.preOrderGearItemAsync(preOrderForm);
        })
      );

    preOrderGearItem(preOrderForm: PreOrderForm) {
        console.log("Pre order form is:", preOrderForm);
        this.preOrderAction.next(preOrderForm);
      }

    preOrderGearItemAsync(preOrderForm: PreOrderForm): Observable<PreOrderForm> {
        if (preOrderForm === undefined) {
          return of(null);
        }
        return this.http
          .post<PreOrderForm>(
            `${this.merchandiseUrl}/${
              preOrderForm.orderDetails.gearItemId
            }/pre-order`,
            JSON.stringify(preOrderForm),
            this.headers
          )
}

Проблема в том, что я не могу получить запрос http для запуска.Я не уверен, что я делаю неправильно.

1 Ответ

0 голосов
/ 30 июня 2019

Ваш код "работает", как вы можете видеть с помощью этого стекаблика: https://stackblitz.com/edit/angular-nm5pcd

Однако могу ли я подчеркнуть 2 пункта и предложить вам улучшения?

1) HTTP-запрос вызывается сразу при инициализации службы (даже без отправки)

Это происходит из-за "нулевого" первого значения BehaviourSubject и из-за === undefined должно быть === null.Или, что еще лучше, вы можете использовать оператор filter.

preOrder$ = this.preOrderAction.asObservable().pipe(
  filter((preOrderForm: PreOrderForm) => !!preOrderForm),
  switchMap((preOrderForm: PreOrderForm) => {
    return this.preOrderGearItemAsync(preOrderForm);
  })
); 

2) Вы также можете рассмотреть другой способ вызова вашего почтового запроса.

a) РешениеA

Держите это очень просто.Так что просто позвоните service.preOrderGearItemAsync из вашего компонента, подпишитесь, получите результат и отобразите его.

this.preOrderService.preOrderGearItemAsync(preOrderForm).subscribe(response => {
  this.result = response;
});

b) Решение B

Как показано в NewPreOrderService в https://stackblitz.com/edit/angular-nm5pcd.

Ваш компонент может вызвать метод preOrderGearItem, который вызывает http.get путем подписки, а затем вызвать next для BehaviourSubject, чтобы сохранить последний результат доступным для вашего компонента.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...