I'd like to execute some logic exactly after ngOnInit()
because i want to decouple the logic from page rendering.
I thought of Angular lifecycle hooks so i put the logic in ngAfterViewInit()
, but seems it get called at the same time as ngOnInit()
.
The code sample:
export class SampleComponent implements OnInit, AfterViewInit{
list = [];
ngOnInit() {
this.localDataService.getData().then( res =>{ //Promise call
for (let o in res) {
this.list.push(res[o]) //the list get loaded
})
}
ngAfterViewInit() { // the intention is to process the list after it's loaded
this.remoteDataService.getData().then(res => {
for (let o in res) {
itemFound = this.list.find( (itemInList) => {return itemInList.id === res[o].id})
//and some code to manipulate the item found from list
itemFound = .... // but the itemFound is always 'undefined'
})
}
}
According to Angular lifecycle hooks, the ngAfterViewInit()
should be execute after ngOnInit()
, but the code running result tells otherwise. The itemFound
in ngAfterViewInit()
is always 'undefined'.
I tried to put the code block from ngAfterViewInit()
to ngOnInit()
, after the promise call,
the itemFound
will get proper value.
Could anyone help explain where went wrong? Is it because the Promise call is Asynchronous?
I realized this with BehaviorSubject
from Rxjs lib, which basically is an observable pattern.
The point is to notify code in ngAfterViewInit()
to start only when the list data is ready.
Code sample:
export class SampleComponent implements OnInit, AfterViewInit{
list = [];
private listSub = new BehaviorSubject([]);
listSubObservab = this.listSub.asObservable();
ngOnInit() {
this.localDataService.getData().then( res =>{ //Promise call
for (let o in res) {
this.list.push(res[o]) //the list get loaded
}
this.listSub.next(this.list) //notify when list is ready
})
}
ngAfterViewInit() { // the intention is to process the list after it's loaded
this.listSubObservab.subscribe(listLoaded => { //observer here, only triggered by notify
this.remoteDataService.getData().then(res => {
for (let o in res) {
itemFound = listLoaded.find( (itemInList) => {return itemInList.id === res[o].id})
//and some code to manipulate the item found from list
itemFound = .... // Finally the itemFound has proper value
}
})
}
}
}