角POST请求未在rxjs catchError()之后传递结果

时间:2020-01-20 19:30:29

标签: angular post rxjs

我正在尝试使用catchError在POST方法中捕获错误。但是,当我收到无效的响应(例如,登录失败)时,代码将执行catchError()(打印console.log),但是我从订阅中看不到控制台消息“收到登录结果”。为什么catchError不将值传递回订阅?请注意,登录成功后一切正常(控制台.log正确打印)

this.auth.login(this.model.username, this.model.password).subscribe(x=>{ 
  console.log('login result received');
  this.loading=false });

我的服务:

login(username: string, password: string): Observable<boolean> {
    return this.http.post<TokenResponse>('/api/auth/token', { name: username, password: password }).pipe(
        catchError(this.appSvc.handleError<boolean>("auth/login", false)),
        map((response: TokenResponse) => {
            if (response !=null) {
                // do token things
                return true;
            }
            else
                alert('rxjs token null')
        }
        ));
}             

public handleError<T>(operation = 'operation', result?: T){
  console.log('got here');
  return of(result as T);}

2 个答案:

答案 0 :(得分:1)

您在管道中错误地使用了catchError。应该是:

catchError(error => this.appSvc.handleError<boolean>("auth/login", false))

另请参见带有工作代码的Stackblitz:https://stackblitz.com/edit/angular-hugqem

答案 1 :(得分:0)

事实证明,由于catchError触发,因此catchError(一个布尔值)的结果被传递给map,然后map试图映射结果。就我而言

  1. catchError返回一个布尔值
  2. 地图正在寻找TokenResponse类型的对象,但没有找到它。因此地图什么也没返回。

我的解决方法是:

  1. 将地图预期的类型从“ TokenResponse”更改为“ any”
  2. 捕获响应类型为布尔值(else if语句)的情况

完整代码:

login(username: string, password: string): Observable<boolean> {
    return this.http.post<TokenResponse>('/api/auth/token', { name: username, password: password }).pipe(
        catchError(this.appSvc.handleError<boolean>("auth/login", false)),
        map((response: any) => {
            if (response.token !=null) {
                // do token things
                return true;
            }
            else if (typeof response==="boolean") //note that catcherror will pass its return type (bool) to here
                    return false
            else
                alert('rxjs token null')
        }
        ));
}