Почему мой эффект работает несколько раз после того, как называется действие? - PullRequest
0 голосов
/ 31 августа 2018

Я имею такой эффект, что запрашиваю несколько значений для извлечения продукта из сервиса. После отправки REQUEST_PRODUCTS вызывается один раз, как и ожидалось, но когда я попытался перейти в другое место в маршрутизации, this.apiMarketServices вызывается несколько раз, это вызывает переход маршрутизатора, и он будет перенаправлен на предыдущую страницу. Действие REQUEST_PRODUCTS отправляется один раз. Почему этот эффект называется несколько раз?

Нужно ли добавлять какой-то стоп к эффекту, чтобы избежать вызова после возврата GetSuccess и GetFailed?

@Effect()
   requestProductsFromMarket = this.actions$
   .ofType(REQUEST_PRODUCTS)
   .withLatestFrom(this.store)
   .switchMap(([action, store]) => {
     const id = store.product.id;
     return this.savedProducts.getProduct(id, 'store');
   })
   .switchMap(_ => this.stateService.getMarketId())
   .switchMap(({ marketId }) =>
     this.apiMarketServices.get(MARKETS_PROFILES + marketId)
   )
   .withLatestFrom(this.store)
   .map(([r, store]) => {
     const ser = r.data.map(s => s.legId);
     const storSer =
       store.product.serIds;
     if (storSer.every(s =>ser.includes(s))) {
        this.router.navigate([
          `/products/edit/${store.products.id}`
        ]);
        return GetSuccess;
    } else {
       return GetFailed;
    }
  })
  .catch(() => of(GetQueryFailed));

1 Ответ

0 голосов
/ 07 сентября 2018

Решение для дефекта связано с наблюдаемой. При отладке «this.apiMarketServices.get (MARKETS_PROFILES + marketId)» вызывался несколько раз, я представлял эти службы как причину неисправности:

.switchMap(({ marketId }) =>
    this.apiMarketServices.get(MARKETS_PROFILES + marketId)
 )

Но настоящей причиной была stateSevice, эта тема поведения была обновлена ​​следующей, в других частях приложения.

.switchMap(_ => this.stateService.getMarketId())

Чтобы избежать этих вызовов, я создал функцию для извлечения текущего значения из BehaviorSubject.

getCurrentMarketId(): ClientData {
   return this.currentMarket.value; // BehaviorSubject
 }

Я добавил эту функцию, чтобы вызывать один раз за отправленный эффект.

 ...
 .switchMap(([action, store]) => {
    const id = store.product.id;
    return this.savedProducts.getProduct(id, 'store');
 })
 .map(_ => this.stateService.getCurrentMarketId())
 .switchMap(({ marketId }) =>
    this.apiMarketServices.get(MARKETS_PROFILES + marketId)
 )
...