Reputation: 329
I have a parent component which contains a bunch of child components. I would like to do some action after all components are loaded.
How to make a call back when all child components are loaded in Angular?
Thanks
PS. I would like a similar function like "ionViewDidEnter" of Ionic in pure Angular.
Upvotes: 4
Views: 4559
Reputation: 15083
I would approach the problem like below:
Declare a service
export class ChildComponentsLoadedService () {
component1LoadedSubject$ = new BehaviourSubject(false)
component2LoadedSubject$ = new BehaviourSubject(false)
component3LoadedSubject$ = new BehaviourSubject(false)
...
allComponentsLoaded$ = combineLatest([
component1LoadedSubject$.asObservable(),
component1LoadedSubject$.asObservable(),
component1LoadedSubject$.asObservable(),
...
]).pipe(
map(componentsLoaded => componentsLoaded.every(loaded => loaded)),
filter(loaded => loaded === true)
)
}
Parent Component
constructor(private childComponentsLoadedService: ChildComponentsLoadedService) { }
childComponentsLoaded$ = this.childComponentsLoadedService.allComponentsLoaded$;
ngOnInit() {
this.childComponentsLoaded$.subscribe({
next: () => {
// Now all components have loaded here
}
})
}
In the child i
component
constructor(private childComponentsLoadedService: ChildComponentsLoadedService) { }
ngOnInit() {
this.componentiLoadedSubject$.next(true)
}
Declare a service
export class ChildComponentsLoadedService () {
componentLoadedSubject$ = new BehaviourSubject([false]);
componentLoadedAction$ = this.componentLoadedSubject$.asObservable()
allComponentsLoaded$ = this.componentLoadedAction$.pipe(
filter(component=> component.every(loaded => loaded))
)
markComponentAsLoaded(index: number) {
let currentLoadStatus = [...this.componentLoadedSubject$.value];
currentLoadStatus[index] = true
this.componentLoadedSubject$.next([...currentLoadStatus])
}
}
Parent Component
constructor(private childComponentsLoadedService: ChildComponentsLoadedService) { }
noOfChildComponents = 14;
ngOnInit() {
this.componentiLoadedSubject$.next(Array(this.noOfChildComponents).fill(false));
this.childComponentsLoaded$.subscribe({
next: () => {
// Now all components have loaded here
}
})
}
Child Component
@Input() componentIndex;
constructor(private childComponentsLoadedService: ChildComponentsLoadedService) {}
ngOnInit() {
this.markComponentAsLoaded(componentIndex)
}
The approach uses the service to communicate between the parent component and the child components
Upvotes: 1