rxjsangular11

Angular 11 how to make one of the http request in higher order mapping conditionally


I want to use a better solution if exists so it will make the following simpler. If this.projectguid is empty then want to use the switchMap call otherwise the other one. Can anyone suggest me a better solution for this?

getWorksheet(): Observable<Worksheet | number> {

    if(this.projectsGuid === '') {
        return this.apiService.get('projects/latest')
        .pipe(
          switchMap((res: {id: string, name: string}) => {
            this.projectsGuid = res.id
            let getUrl = `projects/${this.projectsGuid}/questionnaires/${this.questionnaireId}/worksheets/latest`;
            return this.apiService.get<Worksheet>(getUrl).pipe(
              catchError((err) => {
                return of(err.status);
              })
            );
          })
        )
    } else {
            let getUrl = `projects/${this.projectsGuid}/questionnaires/${this.questionnaireId}/worksheets/latest`;
            return this.apiService.get<Worksheet>(getUrl).pipe(
              catchError((err) => {
                return of(err.status);
              })
            );      
    }
    
}

Solution

  • You could define a projectGuid$ observable that emits the this.projectsGuid value if not empty, and otherwise emits the result of the http call (mapped to just the id):

    const projectGuid$ = this.projectsGuid !== ''
        ? of(this.projectsGuid)
        : this.apiService.get('projects/latest').pipe(
            map(({id}) => id),
            tap(guid => this.projectsGuid = guid)
          );
    

    Then you can pipe the projectGuid to the call to fetch the worksheet:

    return projectGuid$.pipe(
        map(guid => `projects/${guid}/questionnaires/${this.questionnaireId}/worksheets/latest`),
        switchMap(url => this.apiService.get<Worksheet>(url).pipe(
            catchError(err => of(err.status))
        ))
    );