我试图了解如何将值或错误从一个组件传递到另一个组件。 就我而言,我想将错误从服务传递到组件,并且我有嵌套的方法。
这是一个虚拟的例子。 这是服务中引发错误的方法。
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。 现在,我想做的就是以某种方式将值或错误从服务传递给另一个Component中的方法。
这是其他组件中方法的实现方式:
public methodInTheComponent = async () =>{
this.service.serviceMethod(valueOfClass1).subscribe(result => concole.log(result), error2 => console.log(error2));
}
现在,当我运行此命令时,我只会得到error1的输出,而不是error2的输出。
其原因是错误是从方法1引发的,并且没有到达其他方法2和3才能返回错误结果。
我想到的一种解决方案是在服务中使用布尔变量。
像 errorThrown = true 一样,然后将其传递给组件。然后我可以进行订阅检查。
如果errorThrown为true,也应该引发error2。
我不确定这是否是一个好的解决方案!一个问题是我不知道如何将这个 errorThrown 发送到组件!
关于什么可能是一个好的解决方案的任何建议或想法?
答案 0 :(得分:1)
内部可观察对象在外部可观察对象失败时将不会执行。因此,在您的情况下,如果method1引发错误,它将不会执行method2和method3。但是,如果要继续执行内部的可疑对象,则必须捕获错误并将其作为正常值返回,以继续执行。
如下修改服务类以捕获并处理错误:
...
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();
})
);
}
}
请注意,我已经将concatMap
rxjs运算符用于彼此依赖的可观察对象,因为创建嵌套订阅是一种反模式,不建议使用。 concatMap
会为您自动订阅内部可观测对象,因此请勿手动订阅。有关concatMap
的更多信息,请选中此article。
现在在您的组件类中,如下所示从服务类订阅serviceMethod
:
this.service.serviceMethod().subscribe(
val => {
console.log("End result: ", val);
},
err => {
console.error("Error -> ", err);
}
);
现在,即使外部可观察对象抛出错误,您也可以执行它们。有关完整的示例,请参考此Stackblitz project。打开右侧的渲染器控制台以查看结果。