首页 > 解决方案 > 将错误从服务传递到组件

问题描述

我试图了解值或错误如何从一个组件传递到另一个组件。就我而言,我想将错误从服务传递给组件,并且我有嵌套方法。

这将是一个虚拟示例。这是服务中引发错误的方法。

public serviceMethod(value1: Class1): Observable<Interface1>{
    return new Observable(result => {
      this.method1(class1) // this method throws an error and returns an number 
        .subscribe(decimalValue  => this.method2(decimalValue) // this method does an error check and returns an Interface1 type
          .subscribe(value2 => this.method3(value2, result, decimalValue)), error1 => throwError(error1)
        )
    })
  }

由于 method1 抛出错误,error1 也会被抛出。现在我想做的是以某种方式将服务中的值或错误传递给另一个组件中的方法。

这是其他组件中的方法的实现方式:

    public methodInTheComponent = async () =>{
    this.service.serviceMethod(valueOfClass1).subscribe(result => concole.log(result), error2 => console.log(error2));
  }

现在,当我运行它时,我只会得到抛出的 error1 的输出,而不是 error2 的输出。

原因是method1抛出了错误,没有到达其他method 2和3返回错误结果。

我想到的一种解决方案是在服务中使用布尔变量。像errorThrown = true然后将其传递给组件。然后我可以在订阅中进行 if 检查。
如果 errorThrown 为真,error2 也应该被抛出。

我不确定这是否是一个好的解决方案!一个问题是我不知道如何将这个errorThrown发送到组件!

关于什么可能是一个好的解决方案的任何建议或想法?

标签: angulartypescript

解决方案


当外部 Observables 失败时,内部 Observables 不会执行。所以在你的情况下,如果method1抛出错误,它不会执行method2和method3。但是如果你想继续执行内部 observbles,你必须捕获错误并将它们作为正常值返回以继续执行。

如下修改您的服务类以捕获和处理错误:

...
import { of } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable({ providedIn: 'root' })
export class MyService {
  method1() {
    const obs;
    // perform your logic and store the Observable in obs object

    /**
    * catch the error and convert it to a normal observable
    * for execution of inner observable to continue
    */
    return obs.pipe(catchError(err => of(err)));
  }

  // implement method2 and method3 in similar fashion
  ...

  serviceMethod() {
    return this.method1().pipe(
      concatMap(val1 => {
        console.log('result of method1: ', val1);
        return this.method2();
      }),
      concatMap(val2 => {
        console.log('result of method2: ', val2);
        return this.method3();
      })
    );
  }
}

请注意,我已将concatMaprxjs 运算符用于相互依赖的可观察对象,因为创建嵌套订阅是一种反模式,不建议使用。concatMap会自动为你订阅内部 observables,所以不要手动订阅它。有关更多信息concatMap,请查看这篇文章

现在在您的组件类中,订阅serviceMethodfrom 服务类,如下所示:

this.service.serviceMethod().subscribe(
  val => {
    console.log("End result: ", val);
  },
  err => {
    console.error("Error -> ", err);
  }
);

现在,即使外部的 observables 抛出错误,您也可以执行内部的 observables。有关完整示例,请参阅此Stackblitz 项目。打开右侧渲染器的控制台查看结果。


推荐阅读