How to use observable subscription in forloop angular 7

1.2k Views Asked by At

I have an array users:

[0: {id:123, firstname:'xyz', lastname:'abc'}, 1:{id:456, firstname:'foo', lastname:'bar'}, 3:{id:567, firstname:'bar', lastname:'baz'}]

I have to loop through this array and call service API to get user appointments.

Method 1 which i feel is not best practice but solves issue

let userAppointments = []
  for (let user of this.users) {

    this._service
      .getUsersAppointments(
        {
          date: this.todayDate,
          id: user.id
        },
        this.token
      )
      .subscribe(res => {

       // Modifying array as per requirements-----

        userAppointments.push({
          id: user.id,
          name: `${user.firstname} ${user.lastname}`,
          appointments: res
        });
      });

  }

  this.appointments = userAppointments 

method 2: using forkJoin

Issue: I cannot access user firstname and last name when I finally get response from all calls. I need those details in my final array this.appointments i.e after calling subscribe where I am assigning res to this.appointments

        forkJoin(
    this.users
      .map(res =>
        this._service.getUsersAppointments(
          {
          date: this.todayDate,
          id: res.id

          },
          this.token
        )
      )
      .map(response => response)
  ).subscribe(res => {

    // how can I access 'user object' keys like: firstname, id here--------------

    this.appointments = res;

  });

Please let me know if my problem is not clear.

Referred SO answer and codereview question for method 2

1

There are 1 best solutions below

3
On BEST ANSWER

forkJoin emits only once when all the Observables passed into it complete.It emits an Array, whose elements are the results of values emitted by each Observable before it completes. A key characteristic of the emitted Array is that the sequence of elements are the same as the sequence of Observables passed while constructing forkJoin (similar to Promise.all()). This pans out well for the problem you have at hand. You can iterate over the the results from forkJoin, and for each index , pick the corresponding element from the users Array and assign the user properties to the result object. Though this can be done directly in the subscribe call in your method 2 above. A better solution would be to move this code inside a new Observable created using the Observable.create method. This will prevent you from writing the iteration logic everywhere you subscribe to the forkJoin(ed) Observable. I have recreated the same scenario in this stackblitz demo here. Checkout the console for the desired output.