Search code examples
angularreduxrxjsngrxpolling

Why my action is not dispatched after polling with a takeWhile


I have an angular effect that is triggered by myFirstAction and is supposed to poll till a file was created in the back end, and then dispatch another action:

  myEffect = createEffect(() =>
    this.actions$.pipe(
      ofType(Actions.myFirstAction),
      withLatestFrom(
        this.store.select(Selectors.fileName)
      ),
      switchMap(([payload, fileName]) =>
          this.pollTillFileCreated(fileName)),
        map(() => Actions.mySecondAction()),
        catchError((error) => {
           return of(Actions.errorAction(error));
        })
      )
    );

and my polling method is:

  private pollTillFileCreated(fileName: string): Observable<boolean> {
    return timer(0, 1000).pipe(
      concatMap(() => this.service.fileExist(fileName)),
      takeWhile((doesExist: boolean) => !doesExist),
      takeLast(1)
    );
  }

Though I can see that my HTTP call returns doesExist: true, mySecondAction is not being dispatched.


Solution

  • The short answer was I needed to add inclusive: true:

    takeWhile((doesExist: boolean) => !doesExist, true),
    

    The explanation for my issue is, that in my simple case my file is generated quickly in the back-end, so the first poll will return true. so it will be the first and the last poll. when takeWhile is used without inclusive: true it will not keep going until the predicate will return false and will not include it. In that case takeLast(1) will have nothing to take, since we are excluding the last (which is also the first). This way we are not returning anything, so there is nothing to pass to the map.