1

Angular 11: I have a requirement where my mobile website will take users to another apps' popup. Once the user comes back to my mobile website I have to make an HTTP GET call. If response.await===true or an error then after 3 seconds I have to try again and repeat this process, the max attempt is 5. And if the overall process (ie when users come back to my mobile website) is >20sec I have to abort the operation and throw an error.

initiateProcess(){
        let index = 1;
        let tries=4;
        return of(1).pipe(
            switchMap(()=>this.httpService.getFromApi(SOME_API)),
            retryWhen(error=>error.pipe(delay(3000),take(tries),mergeMap(error => {
                if (++index > tries) {
                  return throwError('time out');
                }
                return of(error);
            }))),
        );
    }

This is what I have done so far. But I am stuck.

Naman Jain
  • 61
  • 7
  • The answer from @Mrk Sef should work for retrying per your requirements. If you're looking for more details on "*when users come back to my mobile website*" you'll need to provide some more information and code. (what signifies a 'first visit' from a 'return visit'?) – BizzyBob Oct 04 '21 at 04:32

1 Answers1

2

You can turn your other fail condition into an error, the rest should just follow?

interface ResponseType {
  await: boolean
}

initiateProcess(): Observable<ResponseType> {
  let tries=4;

  const timeout$ = timer(20 * 1000).pipe(
    tap(_ => {throw "Error: 20 Seconds have passed without Api response";})
  );

  const api$ = defer(
    () => this.httpService.getFromApi(SOME_API)
  ).pipe(
    tap((res: ResponseType) => {
      if (res.await) throw "Error: Api response.await === true";
    }),
    retryWhen(error$ => error$.pipe(
      take(tries),
      delay(3000)
    ))
  );

  return merge(api$, timeout$);
}
Mrk Sef
  • 7,557
  • 1
  • 9
  • 21
  • I don't think take(tries) would work with retryWhen – Munzer Sep 29 '21 at 16:11
  • @mrk-sef how to stop this process when users come backs to my website. And how to terminate the whole process after 20 sec? – Naman Jain Sep 29 '21 at 16:22
  • @Munzer Have you tried? Works for me – Mrk Sef Sep 29 '21 at 16:41
  • @NamanJain I've added a 20 second timeout that throws an error. Not sure how you handle users returning to your website (depends on your setup) so I'll leave that to you. – Mrk Sef Sep 29 '21 at 16:55
  • @MrkSef return type of `this.httpService.getFromApi` is `Promise`. Anything that can be done to handle promise? – Naman Jain Oct 04 '21 at 12:31
  • @NamanJain You can use `from` or `defer` to do turn a promise into an observable. I prefer defer as it keeps the action of the observable lazy which is more in line with RxJS. I've updated my answer. – Mrk Sef Oct 04 '21 at 12:55