Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 call function with subscribe inside a for loop

Tags:

angular

I have a function with subscription to a service inside:

selectCar(carNumber) {
  this.carService.getCarByNumerator(carNumber)
    .subscribe( (car) => {
                  console.log(carNumber);
                  //more stuff here
                },
                (err) => console.log(err)
               );
}

I want to call this function inside a for loop as following:

for(let carNumber of carNumbers) {
    this.selectCar(carNumber);
}

The issue is, sometime it works as I expect, but sometimes the order is not as in the list.

E.g. the list is:

45
67
89

but when I look in the console, I see the following:

67
89
45

How can I force the for loop not to go to next item till the current function call finished?

like image 830
Batsheva Avatar asked Jul 25 '17 13:07

Batsheva


2 Answers

If you need to effectively wait for all getCarByNumerator() to complete prior to processing your list of data, you can use the forkJoin operator.

let carNumbers = [1, 2, 3];
let observables = carNumbers.map(carNumber => this.carService.getCarByNumerator(carNumber));

// forkJoin the array/collection of observables
let source = Rx.Observable.forkJoin(observables);

// subscribe and sort combined array/collection prior to additional processing
source.subscribe(x => console.log(x.sort((a, b) => a - b));

Here is JS Bin demonstrating the functionality. The example demonstrates varying delays for returning data from the "API".

Hopefully that helps!

like image 183
Alexander Staroselsky Avatar answered Nov 16 '22 11:11

Alexander Staroselsky


I guess flatMap would help you in this case.

Observable.of(carNumbers)
.flatMap(term => this.selectCar(term))
.subscribe( (car) => {
        console.log(carNumber);
        //more stuff here
    },
    (err) => console.log(err)
);
like image 30
Pankaj Parkar Avatar answered Nov 16 '22 10:11

Pankaj Parkar