angular waiting for a method to finish or a variable to be initialized
Solution 1
remove initializeData()
from constructor and do something like this:
public async initializeData()
{
this.optyList = await this.dataService.getObjectData('opportunities').toPromise();
this.leadList = await this.dataService.getObjectData('leads').toPromise();
}
async ngOnInit()
{
await initializeData();
for(let lead of this.dataStore.leadList){
if(lead.accepted == false)
this.newLeadsList.push(lead)
}
}
I made code from head so it can have some bugs - may be async should be also before function ngOnInit()
... check this.
Async-await-toPromise make that your asynchronous function behaves as synchronous function... and JS wait until your toPromise finish before execute another promise...
UPDATE
If I understand you right: you wanna call your service "DataStoreService.initializeData()
" once and use it in future in other components (without calling initializeData again) - ? - if yes then you need Service singleton (which can also use inside above async-await technique)
Solution 2
What you can utilize is observables, in this case a BehaviorSubject
which you subscribe to and always emits if there is a subscriber. After making the initial request, just call next
and all components that are subscribing will get the value... when it eventually arrives:
DataStoreService:
import {BehaviorSubject} from 'rxjs/BehaviorSubject';
// ...
leadList: LeadModel[]
leadList$ = new BehaviorSubject<LeadModel[]>([])
constructor(public dataService:DataService){
this.initializeData()
}
initializeData() {
this.dataService.getObjectData('leads')
.subscribe((data) => {
this.leadList = data;
this.leadList$.next(this.leadList)
})
}
Then in your components, subscribe to leadList$
:
leadList = <LeadModel[]>[];
ngOnInit() {
this.dataStore.leadList$.subscribe(data => {
this.leadList = data;
// do your magic here :)
})
}
Then remember to unsubscribe when component is destroyed!
Vik
http://www.oracle.com/innovation/innovator-vivek-kumar.html http://adfjsf.blogspot.com http://www.linkedin.com/vikceo http://www.twitter.com/vikceo
Updated on June 18, 2022Comments
-
Vik almost 2 years
I have a service used as a local data store to share data across the app. This service makes a few rest calls in the beginning to initialize some data. It look like this:
Injectable() export class DataStoreService { leadList: LeadModel[] optyList: ContactModel[] constructor(public dataService:DataService){ this.initializeData() } initializeData() { this.dataService.getObjectData('opportunities').subscribe( (data) => this.optyList = data ) this.dataService.getObjectData('leads').subscribe( (data) => this.leadList = data ) } }
I have a component page where I do below:
ngOnInit() { for(let lead of this.dataStore.leadList){ if(lead.accepted == false) this.newLeadsList.push(lead) } }
It is very obvious that if initialize data fails to finish the leadList may be undefined and this ngOnInit for loop will crash as well. So, how do I wait in the ngOnInit until initializeData finishes?