RxJS retry and then catchError not working

Viewed 233

I have an observable:

public updateThingName(name: string, thingId: number): Observable<any> {
    console.log('attempting rename');
    return this.http
        .put(
          `${this.thingApi}/projects/${thingId}`, 
          { name },
          this.options,
      ).pipe(
          map(response => response.data.id)
      );
}

called as part of a longer chain:

    return this.projectService.getProject(id).pipe(
            switchMap(prevProjectData => {
                return this.projectService.updateProject(id, data).pipe(
                    map(newProjectData => ({prevProjectData, newProjectData}))
                )
            }),
            switchMap(({prevProjectData, newProjectData}) => {
                return this.thingService.updateThingName(newProjectData.title, newProjectData.thingId)
                  .pipe(retry(5),catchError(err => {
                      return this.projectService.revertProjectUpdate(err, prevProjectData);
                }))
            }),
            tap(() => { ... save to logs only when successful ... })
        );

I want to try to rename something, if it fails retry 5 times, if it still fails then catch the error, revert the earlier changes and throw the final error in the revert function. The reverting and sending the error response back to the front end works fine but no matter where I put the retry(5) I only ever see the initial console.log('attempting rename'); in the logs.

Am I miss using the retry? How do I get this to work?

This is backend code on NestJS so I don't handle the final subscribe aspects directly if that makes a difference.

Thanks!

1 Answers

That should be correct. The methodos called once but it tries to resubscribe multiple times. You should be able to see it if you log a message on every subscribe:

public updateThingName(name: string, thingId: number): Observable<any> {
  return defer(() => {
    console.log('attempting rename');
    return this.http
      .put(
        `${this.thingApi}/projects/${thingId}`, 
        { name },
        this.options,
    ).pipe(
        map(response => response.data.id)
    );
  )};
}
Related