admin管理员组文章数量:1434235
I am on Angular 2.3.1 and I am fairly new to both Angular and event based programming. I have two subscriptions, route.params.subscribe
and engineService.getEngines()
. In my onInit
I want to call getEngineName
after this.route.params.subscribe
and this.engineService.getEngines().subscribe
plete.
Reason for this: getEngineName
functions depends on the engineId
from the queryParams and the engines
array which is populated after the pletion of getEngines()
call.
I did look at flatMap
and switchMap
but I did not pletely understand them.
This is the code in the ponent:
export class ItemListComponent implements OnInit {
items: Item[];
engines: Engine[];
private engineId: number;
constructor(
private router: Router,
private route: ActivatedRoute,
private itemService: ItemService,
private engineService: EngineService
) {}
ngOnInit() {
this.route.params.subscribe((params: Params) => {
this.engineId = +params['engineId'];
// itemService is irrelevant to this question
this.itemService.getItems({engineId: this.engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
});
this.engineService.getEngines()
.subscribe(engines => this.engines = engines);
// This should only run after engineId and engines array have been populated.
this.getEngineName(this.engineId);
}
getEngineName(engineId: number) {
this.engines.find((engine) => {
return engine.id === engineId;
})
}
}
I am on Angular 2.3.1 and I am fairly new to both Angular and event based programming. I have two subscriptions, route.params.subscribe
and engineService.getEngines()
. In my onInit
I want to call getEngineName
after this.route.params.subscribe
and this.engineService.getEngines().subscribe
plete.
Reason for this: getEngineName
functions depends on the engineId
from the queryParams and the engines
array which is populated after the pletion of getEngines()
call.
I did look at flatMap
and switchMap
but I did not pletely understand them.
This is the code in the ponent:
export class ItemListComponent implements OnInit {
items: Item[];
engines: Engine[];
private engineId: number;
constructor(
private router: Router,
private route: ActivatedRoute,
private itemService: ItemService,
private engineService: EngineService
) {}
ngOnInit() {
this.route.params.subscribe((params: Params) => {
this.engineId = +params['engineId'];
// itemService is irrelevant to this question
this.itemService.getItems({engineId: this.engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
});
this.engineService.getEngines()
.subscribe(engines => this.engines = engines);
// This should only run after engineId and engines array have been populated.
this.getEngineName(this.engineId);
}
getEngineName(engineId: number) {
this.engines.find((engine) => {
return engine.id === engineId;
})
}
}
Share
Improve this question
edited Jan 9, 2017 at 20:34
eko
40.7k11 gold badges78 silver badges101 bronze badges
asked Jan 9, 2017 at 20:17
YathiYathi
1,0611 gold badge14 silver badges21 bronze badges
1
- you could use bineLatest. Your problem is similar to this one: stackoverflow./questions/40872357/… With bineLatest you don't need to nest subscriptions. – chrigu Commented Jan 9, 2017 at 20:32
2 Answers
Reset to default 4Why don't you just move the logic inside the route.params
callback?
this.route.params.subscribe((params: Params) => {
this.engineId = +params['engineId'];
// itemService is irrelevant to this question
this.itemService.getItems({engineId: this.engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
//this.engineId is defined here (1)
this.engineService.getEngines()
.subscribe((engines) => {
this.engines = engines;
//this.engines is defined here (2)
this.getEngineName(this.engineId);
});
});
with flatMap
and forkJoin
:
this.route.params.flatMap((params: Params) => {
this.engineId = +params['engineId'];
return Observable.forkJoin(
this.itemService.getItems({engineId: this.engineId}),
this.engineService.getEngines()
)
}).subscribe((data)=>{
let items = data[0];
let engines = data[1];
this.items = items;
this.engines = engines;
this.getEngineName(this.engineId);
});
switchMap
is remended in this scenario.
this.route.params.pluck('engineId') //pluck will select engineId key from params
.switchMap(engineId => {
this.getItems(engineId);
return this.engineService.getEngines().map(engines => {
/*this.engineService.getEngines() emits the list of engines.
Then use map operator to convert the list of engines to engine we are looking for
*/
return engines.find((engine) => {
return engine.id === engineId;
})
})
}).subscribe(engine => {
//engine
})
getItems(engineId) {
this.itemService.getItems({engineId: engineId})
.subscribe((items: Item[]) => {
this.items = items;
});
}
Suppose the engineId in the params changes, the first observable this.route.params.pluck('engineId')
will emit data, which will cause the next observable this.engineService.getEngines()
to get fired. Now suppose the route changes before this observable emits the data. Here you need to cancel getEngines
observable to prevent error. This is done by switchMap
.
switchMap
cancels inner observable if outer observable is fired.
PS: I have avoided keeping any states like this.engineId
etc.
本文标签: javascriptHow to call a function after the completion of two Angular 2 subscriptionsStack Overflow
版权声明:本文标题:javascript - How to call a function after the completion of two Angular 2 subscriptions? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744531952a2611088.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论