实际上,我想使用数组值作为参数来调用另一个函数。我从一个主题获取数组:
this.shopService.$getShops().pipe(map(
shops => {
console.log(shops[0]);
}
)).subscribe();
订阅基于此:
private newShopsSubj = new BehaviorSubject(undefined);
setShops(shops: any) {
this.newShopsSubj.next(shops);
}
$getShops(): Observable<any> {
return this.newShopsSubj.asObservable();
}
实际上,代码正在运行...但是console.log
调用以undefined
结尾。不知何故我找不到合适的解决方案。
我想做:
this.shopService.$getShops().subscribe(resp => {
this.shopService.getProductsByShopID(resp[0].id).subscribe(resp
=> {do something...};});
但是实际上却失败了,因为resp[0].id
停留在undefined
...
我对地图的尝试失败。
任何帮助表示赞赏...
谢谢
Hucho
答案 0 :(得分:2)
与其他答案类似...如果在设置值之前调用$getShops()
,则会得到undefined
,因为它是初始值。您可以将其初始化为空数组,或使用rxjs filter
过滤掉undefined
值。另外,我会将这些请求与switchMap
或mergeMap
链接在一起,因为不建议嵌套订阅。所以我建议如下:
private newShopsSubj = new BehaviorSubject([]);
public newShopsSubj$ = this.newShopsSubj.asObservable();
和组件代码:
import { mergeMap, filter } from 'rxjs/operators';
import { of } from 'rxjs';
// ...
this.shopService.newShopsSubj$.pipe(
mergeMap((shops: any[]) => {
// do a check that that there is an object
if (shops && shops.length) {
return this.shopService.getProductsByShopID(shops[0].id)
}
// no shops, so return...
// empty array, since assuming the above function returns array of products
return of([]);
})
).subscribe((products: any[]) => {
// check if products exist and do your magic!
})
或如前所述,将您的BehaviorSubject初始值设为undefined
,并将filter
除去这些值:
this.shopService.newShopsSubj$.pipe(
filter(shops => !!shops)
mergeMap((shops: any[]) => {
// .....
请注意,我在这里使用了any
。不要使用它。将数据输入模型! (我更喜欢接口)。
,请记住退订OnDestroy
!
答案 1 :(得分:0)
BehaviourSubject
将当前值发送给新订阅者。
在这里,您要使用undefined
初始值进行初始化
private newShopsSubj = new BehaviorSubject(undefined);
因此,当您按以下方式订阅时
this.shopService.$getShops().subscribe(resp => {
this.shopService.getProductsByShopID(resp[0].id).subscribe(resp
=> {do something...};});
最初,它将得到resp
作为未定义。
要解决此问题,您可以使用Subject
代替BehaviorSubject
或使用适当的shop对象初始化BehaviourSubject
。