HTTP服务在参数初始化之前激发



我在项目中使用angular 10。我在ngOnInit函数中嵌套了HTTP调用,如下所示:

ngOnInit(): void  {

let communetyid;

this.route.data.subscribe(data => { 
this.route.params.subscribe(params => { 

if(data.category === "code")
{
this.dataService.getCode(params.code)
.subscribe(resp => { communetyid = resp.results.communityId });
}
else  
{
communetyid = params.id
}
this.dataService.getCommunityById(communetyid)
.subscribe(response => { this.community = response.results; 

///other http calls

}) 
})
})
})

正如您在上面的代码中看到的,dataService.getCommunityById获取参数communietyid,communietyide获取if语句中的值。由于异步dataService.getCommunityById函数在communityid获取值之前触发,我在控制台中得到了错误。

我如何更改代码,即当dataService.getCommunityById被激发时,值communietyid将被初始化。

我知道我可以在dataService.getCode的订阅中复制dataService.getCommunityById,但我想防止代码重复。

如果你想保持你使用的原始模式(嵌套订阅(,你应该只移动"getCommunityById";http调用到";dataService.getCode";回调,它就会工作。这里的关键点是要理解";dataService.getCode";将返回一个可观察的(不存在的数据(,而您的else分支使用已经存在的值(params.id(。解决这个问题的正确方法是在pipe((内部使用concatMap((并将这些操作链接起来。在concatMap((回调中,您将处理if-else分支逻辑,在那里您将返回this.dataService.getCode或Observable.of(params.id(,而在下一个concatMap((中您将使用此值作为this.dataServices.getCommunityById.的参数

您可以考虑使用更高阶的operators链接您的Observables

export class ChildComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private dataService: DataService
) {}
// Extract Parameters from the Activated Route
params$ = this.route.paramMap.pipe(
map(params => ({
id: params.get("id"),
code: params.get("code"),
category: params.get("category")
}))
);
// Get Community Id
communityId$ = this.params$.pipe(
mergeMap(({ category, code, id }) =>
category === "code"
? this.dataService
.getCode(code)
.pipe(map(({ results }) => results.communityId))
: of(id)
)
);
// Get Community
community$ = this.communityId$.pipe(
switchMap((communetyId) => this.dataService.getCommunityById(communetyId))
)
ngOnInit() {
this.community$.subscribe({
next: console.log
});
}
}

代码说明

提取参数

params$ = this.route.paramMap.pipe(
map(params => ({
id: params.get("id"),
code: params.get("code"),
category: params.get("category")
}))
);

我使用paramMapActivatedRoute中提取参数。从Angular Docs来看,params已被弃用(或将被弃用(

ActivatedRoute包含两个性能不如其替代品的属性,并且可能在未来的Angular版本中被弃用。

下一步,我们定义一个属性communityId,其值取决于通过检查category属性映射params。我正在使用mergeMap运算符来合并params$communityId$的订阅。

最后的步骤是得到community$。这里我们使用switchMap。如果有新的请求,我们不想继续最初的请求,因此这个运营商是这里最合适的

查看示例

将代码更改为以下内容:-

ngOnInit(): void  {

let communetyid;

this.route.data.subscribe(data => { 
this.route.params.subscribe(params => { 

const communityIdObs = date.category === 'code' ? this.dataService.getCode(params.code).pipe(map(resp => resp.results.communityId)) : of(params.id);
communityIdObs.pipe(mergeMap(res => {
return this.dataService.getCommunityById(communetyid);
}).subscribe(response => { 
this.community = response.results; 
///other http calls
});
})

Mergemap操作员会按顺序调用,我也修改了代码,使其更短。

我认为您可以使用concatMap操作员

要将一个响应转换为连续请求所需的参数,请使用concatMap

运算符concatMap()在内部订阅从其投影函数返回的Observable,并等待直到它完成,同时重新发出其所有值。

以下是的示例

function mockHTTPRequest(url) {
return Observable.of(`Response from ${url}`)
.delay(1000);
}
let urls = ['url-1', 'url-2', 'url-3', 'url-4'];
let start = (new Date()).getTime();
Observable.from(urls)
.concatMap(url => mockHTTPRequest(url))
.timestamp()
.map(stamp => [stamp.timestamp - start, stamp.value])
.subscribe(val => console.log(val));

Event尽管您可以使用rxjs来链接可观测值。还有另一种简单的方法可以解决你的问题。如果你把任何东西放在可观察的订阅中,它就会被执行,所以你需要把它作为一个单独的函数移到外部。它应该可以帮助您防止调用dataService.getCommunityById函数。

ngOnInit(): void  {
let communetyid;
this.route.data.subscribe(data => { 
this.route.params.subscribe(params => { 

if(data.category === "code")
{
this.dataService.getCode(params.code)
.subscribe((resp) => 
{ 
communetyid = resp.results.communityId;
getCommunityData(communetyid);
});
}
else  
{
communetyid = params.id;
getCommunityData(communetyid);
}
})
})  
})
getCommunityData(communetyid) {
this.dataService.getCommunityById(communetyid)
.subscribe(response => { 
this.community = response.results;
//other http calls
})
}

这是使用rxjs的另一种方法,这更容易理解。您还可以使用rxjs运算符,如concatMap,如Medhat MahmoudMuhammet can TONBUL所建议的。

相关内容

  • 没有找到相关文章

最新更新