0

I'm using angular and I need to emit a new event when my for each finishes the post requests for every element.

the elements are users and for each one I need to make a post request to register them on my server.

This is my code:

export class CustomerBulkImport {
@Output() customersAdded = new EventEmitter<boolean>();
...
...
registerCustomers(){

  let usersRegistered = this.records.forEach( customer=>{
    customer.owner = this.owner

     this.service.register(this.strategy,customer).subscribe((res:NbAuthResult)=>{

      this.submitted = true;
      if (res.isSuccess()) {
        this.messages = res.getMessages();
        this.tokenStorage.set(this.currentToken)
      } else {
        this.errors = res.getErrors();
      }
      this.cd.detectChanges();
    })
  });


  this.customersAdded.emit(true)
  console.log('emitted')

 }
}

As you can see here, my console.log('emitted') is executing before the forEach ends.

enter image description here

Daggle
  • 171
  • 1
  • 1
  • 10

1 Answers1

2

This is because of asynchronous nature of observables. you can use forkjoin to hit multiple parallel calls and subscribe to them so that you can know when all have completed.

registerCustomers(){
let myCalls = this.records.map((customer) => {
  customer.owner= this.owner;
  return this.service.register(this.strategy, customer).pipe(map(res:NbAuthResult) => {
      this.submitted = true;
      if (res.isSuccess()) {
        this.messages = res.getMessages();
        this.tokenStorage.set(this.currentToken)
      } else {
        this.errors = res.getErrors();
      }
      this.cd.detectChanges();
  }));
});
forkJoin(myCalls).subscribe(() => {
  this.customersAdded.emit(true)
  console.log('emitted')
});
} 
Aakash Garg
  • 10,649
  • 2
  • 7
  • 25
  • Thanks it worked for me, I've also noticed that you used .map instead of .forEach() and you returned the service call. I hope some day I can finally understand when to use .forEach() or when to use .map() – Daggle May 26 '20 at 13:26
  • map will return new array. i collected all the service calls in a array with there mapping logic inside pipe. Since they will only be called when i forkjoin them or subscribe them individually. All the things are in your control now. – Aakash Garg May 26 '20 at 13:29