6

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?

2
  • you can change your function to a recursive one,that will help but cost of that will increase. Commented Jul 25, 2017 at 14:18
  • Asynchronous calls are being made to an API/backend, you can't guarantee data will be returned in a specific order. Can you simply sort/order the results before additional processing/display? Otherwise you can consider operators such as combineAll or Subject Commented Jul 25, 2017 at 14:22

2 Answers 2

9

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!

Sign up to request clarification or add additional context in comments.

Comments

2

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)
);

1 Comment

Thanks for your answer. I have 2 questions about it: 1. seems that the content of selectCar will occur twice, no? as you both call it and later do the stuff of it again. 2. If I try this, I get an error in the part that I am trying to send term to the selectCar. It says that it accept a single car number but gets a whole array. what it the term type? one item of the array or all array?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.