Reputation: 1694
Scenario : When i load a page, it calls several services and loads them up in several combo box. The user should not be able to input values until all the services are finished loading the combo box. so when i load this page, i immediately start a spinning loader and when all the services are finished, i stop the spinning loader. To achieve this, i used something like this.
Code:
this.globalService.ShowLoader(true);
...
this.consultantService.getAllConsultants().then(consultants => {
this.consultants = consultants;
}).then(() => {
this.divisionService.getAllDivisions1().then(divisions => {
this.divisions = divisions;
}).then(() => {
this.entityService.getAllEntity1().then(entities => {
this.entities = entities;
}).then(() => {
this.roleService.getAllRoles1().then(roles => {
this.roles = roles;
}).then(() => {
this.isLoaded = true
})
})
});
})
...
ngAfterViewChecked() {
if (this.isLoaded) {
loadLister();
this.globalService.ShowLoader(false)
this.isLoaded = false
} }
This works but this is a workaround. I need to know whether is there any other better alternative for this process. Any advice would be helpful. Thank You.
Upvotes: 0
Views: 269
Reputation: 41314
You can try this:
Observable.forkJoin(
this.consultantService.getAllConsultants(),
this.divisionService.getAllDivisions1(),
this.entityService.getAllEntity1(),
this.roleService.getAllRoles1()
).subscribe(values => {
const [consultants, divisions, entities, roles] = values;
this.consultants = consultants;
....
this.isLoaded = true;
})
You can check out other alternatives with observables at this blog post.
Upvotes: 1
Reputation: 8879
I'm not entirely sure whether or not you're just asking if this can be written in a more elegant way, or if there is a certain problem that can replace your "work around".
Assuming the first, yes, this can be written a lot easier. Since you have no dependencies between your asynchronous functions, you can run them in "parallel" instead of forcing it to run sequentially.
//Declare an empty array
var promises = [];
//Push each promise to the array
promises.push(this.consultantService.getAllConsultants());
promises.push(this.divisionService.getAllDivisions1());
promises.push(this.entityService.getAllEntity1());
promises.push(this.roleService.getAllRoles1());
//Use Promise.all() to await all promises.
//The .all() function resolves a new promise as soon
//as all promises in the passed array are resolved,
//or rejects the promise if any promise is rejected
Promise.all(promises).then((results:any[]) => {
//Results is an array that will look like
//[consultants, divisions, entities, roles]
})
.catch(function(err){
//Handle error
});
Upvotes: 2