http.post 订阅从服务到组件的链接错误

Error chaining from a service to component for a http.post subscription

我正在使用 firebase 对登录进行身份验证,然后向我的后端发送请求,为登录用户创建自定义会话令牌。为此,我将函数调用从 component.ts 发送到 service.ts。



  SignIn(email: string, password: string) {
    return this.angularFireAuth
      .signInWithEmailAndPassword(email, password)
      .then(async res => {
        const idToken = await res.user.getIdToken()
        this.http.post(environment.baseURL + "auth/sessionLogin", { idToken: idToken }).pipe(
          catchError(err=>{
            return throwError("FailedLogin")   // ** NOT USEFUL ERROR 
          })
        )
        .subscribe((response) => {
          this.router.navigate(["/signup"]);    // ** IF SIGN IN IS SUCCESSFUL
        }
        // , (err) => {
        //   throw new Error("Failed Login").   // ** NOT USEFUL ERROR
        // }
      )
        return { loggedIn: false, message: "Failed Login" }   // ** INCASE MY BACKEND THROWS ERROR

      }).catch(err => {
        return { loggedIn: false, message: err.message }.  // ** INCASE FIREBASE THROWS ERROR

      });
  }

component.ts代码是

  async signIn(loginF: NgForm) {
    const email = loginF.value.email
    const password = loginF.value.password
    const response = await this.authenticationService.SignIn(email, password)
    if(!response.loggedIn){
      // my error handling code for flash messages
    }

  }

现在,上面的代码完成了工作,但我知道这是最糟糕的错误处理方式之一,因为我没有充分利用可观察对象的潜力。我想知道如何使用 catchError 或 try-catch 块来不手动发送和检查自定义 { loggedIn: false, message: err.message } like object to my组件。

上面的 catchErrors 基本上没有用,因为它们没有被转发到我的组件。如果我 return this.http.post..,它说这是一个订阅,我不能在上面做 .then() + 它说 response 在我的前端将是订阅类型或类型 { loggedIn: false, message: err.message }

更新:一个可能的答案

我已经分解了两件事:使用 firebase 登录,然后将令牌请求发送到后端分为两个不同的部分。它看起来是一个更优雅的解决方案,因为它不涉及任何手动响应对象创建。

** component.ts**
  async signIn(loginF: NgForm) {
    const email = loginF.value.email
    const password = loginF.value.password
    let idToken
    try{
      idToken = await this.authenticationService.SignIn(email, password)
    }catch(err){
      idToken = null;         // ** INCASE FIREBASE FAILS
      // error handling for flash messages
    }


    if(idToken!= null){
      this.authenticationService.SignInBackend(idToken).subscribe((response) => {
        this.router.navigate(["/signup"]);
      }
      , (err) => {
        // error handling for flash messages // ** INCASE BACKEND FAILS
      }
    )
    }

  }
** service.ts**
SignIn(email: string, password: string) {
    return this.angularFireAuth
      .signInWithEmailAndPassword(email, password)
      .then(async res => {
        const idToken = await res.user.getIdToken()
        return idToken;
      }).catch(err => {
        throw new Error(err.message).      // ** ERROR GETS CHAINED
      });
  }

  SignInBackend(idToken){
    return this.http.post(environment.baseURL + "auth/sessionLogin", { idToken: idToken })

  }