Angular : Receive responses in order with the calls

261
December 03, 2017, at 6:43 PM

Hi I am pretty new to Angular and Observables

I am trying to GET Objects by theirs ID through a loop. But don't receive my Response in Order.

Example

get ID(1)
get ID(2)
get ID(3)
Receive Object ID(2)
Receive Object ID(3)
Receive Object ID(1)

Is it possible to get my Objects back in order ?? Below is where I call multiple times my service function :

conferences-attendance.component.ts

  ExportExcelAttendance() { 
    for (var i = 0; i < this.contactsAttendance.length; i++) { 
      this.practiceService.GetPracticebyDBID(this.contactsAttendance[i].practiceId) 
        .subscribe( 
        (practice: Practice) => { 
          this.practicesAttendance.push(practice); 
          if (this.practicesAttendance.length == this.contactsAttendance.length) { 
            this.ExportExcelAttendance2(); 
          } 
        }, 
        error => this.errorMessage = <any>error 
        ); 
    } 
  }

Here is my function in my service, it where I receive the data (not in order with the calls).

practices.service.ts

    GetPracticebyDBID(id: string) { 
        let params: URLSearchParams = new URLSearchParams(); 
        params.set('thisId', id); 
        let requestOptions = new RequestOptions(); 
        requestOptions.params = params; 
        return this.http.get('http://ec2-34-231-196-71.compute-1.amazonaws.com/getpractice', requestOptions) 
            .map((response: Response) => { 
                return response.json().obj; 
            }) 
            .catch((error: Response) => Observable.throw(error.json())); 
    }

Answer 1

forkJoin gives you a little less code,

const arrayOfFetches = this.contactsAttendance
  .map(attendee => this.practiceService.GetPracticebyDBID(attendee.practiceId) );
Observable.forkJoin(...arrayOfFetches)
  .subscribe((practices: Practice[]) => {
      this.practicesAttendance = practices;
      this.ExportExcelAttendance2();
  });

Edit Snap! @Anas beat me to it. Although, I don't think you need the concatAll()

Answer 2

you should use concatAll operator to ensure calling your observables in sequence.

also, you can use completed callback to call ExportExcelAttendance2 instead of checking practicesAttendance length on every response callback.

check the below example:

let contactsAttendanceObservables = this.contactsAttendance
  .map((item) => {
    return this.practiceService.GetPracticebyDBID(item.practiceId);
  });
Observable.of(...contactsAttendanceObservables)
  .concatAll()
  .subscribe(
    (practice: Practice) => {
      this.practicesAttendance.push(practice);
    },
    (err) => {
      // handle any errors.
    },
    () => {
      // completed
      this.ExportExcelAttendance2();
    }
  );

if you still want your observables to run in parallel, you can use forkJoin Operator, which will emit the last value of all the passed observables to a one subscriber when all observables are completed.

check the below example:

let contactsAttendanceObservables = this.contactsAttendance
  .map((item) => {
    return this.practiceService.GetPracticebyDBID(item.practiceId);
  });
Observable.forkJoin(...contactsAttendanceObservables)
  .subscribe(
    (practices: Practice[]) => {
      this.practicesAttendance = practices;
      this.ExportExcelAttendance2();
    }
  );
Answer 3

The forkJoin operator is simple to use. It waits until all observables complete, then emit an array with all the items emitted.

ExportExcelAttendance() { 
  const all = this.contactsAttendance.map(it => this.practiceService.GetPracticebyDBID(it.practiceId)); 
  Rx.Observable.forkJoin(all) 
    .subscribe( 
      practicesAttendance => this.ExportExcelAttendance2(practicesAttendance), 
      error => this.errorMessage = < any > error); 
}

Rent Charter Buses Company
READ ALSO
Can someone help me convert this Curl request into node.js?

Can someone help me convert this Curl request into node.js?

I'm working with Webhooks and I am trying to run a Curl request from my nodejs code

346
Node.js Array not rendering

Node.js Array not rendering

I am having trouble rendering the array i make in the js file in the jade viewI am not sure why it is not working This is how I am adding the data to the array

390
TypeError: Parameter url must be string, not object

TypeError: Parameter url must be string, not object

Came across this error, but i am very confused as to why i'm getting it because the url i'm using in my twitterClientget is a string

351
callback function in .each() method for Async package in Node.js

callback function in .each() method for Async package in Node.js

In the document of Async package, each() method takes 3 argument each(coll, iteratee, callback)My question is not about the 3rd argument callback, but the another "callback" function in the 2nd argument iteratee

212