Dino
Dino

Reputation: 8292

Angular trigger child function once parent finishes with observables in forEach

In parent component I am pushing the response of observables to an array which I am passing to child component.

parent.component.ts

let categoriesArr = [];

for (let category of listing.categories) {
      this._projectService.getCategories().subscribe((data) => {
             this.categoriesArr.push(data);
       });
}

parent.component.html

<child-comp #childComp [categories]="categoriesArr"></child-comp>

In the child component I want to call a specific function once the for loop of observables is finished in parent function.

child.component.ts

@Input() public categories;

public limitCategories() {
**//I want to call this function from parent once the for loop with observables is finished**
...
}

child.component.html

<div class="Category" *ngFor="let item of categories">
...
</div>

I've tried making the categoriesArr as an Observable, and then subscribe to it in the child component, but then I would call limitCategories() every time there's a change. I want to call it only once after the last call to the service is made.

Upvotes: 0

Views: 1697

Answers (2)

user4676340
user4676340

Reputation:

Use the forkJoin operator :

const calls$ = listing
  .categories
  .map(category => this._projectService.getCategories(category))

forkJoin(calls$).subscribe(data => {
  this.categoriesArr = [...data];
  this.childComp.limitCategories();
})

Once all of your HTTP calls have been made, forkJoin will call the child method.

I'm not saying your implementation is the best solution, but this should do the trick for you.

Upvotes: 0

Harun Yilmaz
Harun Yilmaz

Reputation: 8558

You could use @ViewChild decorator to get child reference as ChildComponent:

parent.component.ts

@ViewChild('childComp', {read: ChildComponent})
childComp: ChildComponent;

Then in the loop, you could call limitCategories() method:

for (let category of listing.categories) {
  this._projectService.getCategories().subscribe((data) => {
         this.categoriesArr.push(data);

         this.childComp.limitCategories();

   });
}

UPDATE

If you would like to wait the loop of async operations and trigger limitCategories() after the last async operation, you could use async/await to wait for operations to finish.

parent.component.ts

ngOnInit(){
  this.getCategories();
}


getCategories = async () => {
    for (let category of listing.categories) {
       await this._projectService.getCategories().toPromise().then((data) => 
       {
           this.categoriesArr.push(data);
       });
    }

    this.childComp.limitCategories();

}

Upvotes: 1

Related Questions