Home > Net >  Angular RxJS sequential requests issue
Angular RxJS sequential requests issue

Time:01-06

I have the following requests;

  public userLogin(username: string, password: string) {
    return this.http.post<any>(`${this.apiURL}/login `, {username, password}, constants.httpOptions)
      .pipe(
        map((response) => {
          this.setToken(response.token);
        })
      );
  }

  public getUser() {
    return this.http.get<IUser>(`${this.apiURL}/api/account`)
      .pipe(
        map((user: IUser) => {
          sessionStorage.setItem('user', JSON.stringify(user));
          this.userSubject.next(user);
        })
      );
  }

I would like to call them sequentially and check the returned value of the last request. I implemented the following block of code however, the console.log output is undefined within the subscribe section. In the network tab, I can see that both requests are called sequentially and there's no error.

this.authService.userLogin(username, password).pipe(
        concatMap(() => { return this.authService.getUser() })
      ).subscribe((res: any) => {
        console.log(res);
        this.router.navigate(['/home']);
      }, (err: HttpErrorResponse) => {
        if (err.status === 401) {
          console.log('sign-in page - 401');
          this.unauthorized = true;
        }
      });

What am I doing wrong?

CodePudding user response:

This is an example of a good reason to specify return types in TypeScript. If you had you'd realize that the result of the map operator in getUser is always undefined. In this case I think you want to use tap which allows you to perform a side-effect while passing the source emission further through the stream.

public getUser(): Observable<IUser> {
  return this.http.get<IUser>(`${this.apiURL}/api/account`).pipe(
    tap((user: IUser) => {
      sessionStorage.setItem('user', JSON.stringify(user));
      this.userSubject.next(user);
    })
  );
}

You probably want to use tap in setToken as well if you intend on returning the token value from that method.

CodePudding user response:

The map operator on your getUser Observable doesn't return anything. Have it return what the Observable is supposed to emit, and you'll get something in the response.

Also, putting logic in a subscribe callback is not best practice. Use tap to implement side effects.

  •  Tags:  
  • Related