1

I have a nested for loop and internal loop also makes service calls in angular 2

public populateData: any[] = [];

let appCounter = 0;
this.list.forEach(data => {       <---- outer loop
    this.service.getSubs(data.id).subscribe(res => { <---- backend call to get data
            let subscriptions = res.subscriptions;

            subscriptions.forEach(subscription => {
                if(condition){
                    this.populateData.push(subscription);   
                }
            });     
    }); 
    appCounter++;
    if(appCounter == this.list.length){
        console.log('--------- subscriptionList ----------');
        console.log(this.populateData);
    }
});

I want to call a method after populateData variable is populated by executing outer loop completely.

currently, it gives me empty array in the console, because outer loop executes completely while inner HTTP calls are still pending.

3
  • seems that promises are here for you, more precisely Promise.all. Or you can do it the old school way by incrementing a variable inside the callback and test if all responses arrived, so you can trigger the rest of the code (all this inside the callback, except the var that needs not to loose its value between steps) Commented Nov 24, 2017 at 8:56
  • if i print appCounter variable in getSubs service call, it prints value equal to size of this.list, because even for first service call outer loop is executed and appCounter is incremented. Commented Nov 24, 2017 at 9:31
  • the counter increment and the test of its value must be inside the async call's callback for this to work Commented Nov 24, 2017 at 9:33

1 Answer 1

1

You may have some luck with forkJoin:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

public populateData: any[] = [];
public observables: any[] = [];

this.list.forEach(data => { 
  this.observables.push(this.service.getSubs(data.id)); 
});

Observable.forkJoin(this.observables)
  .subscribe(res => {
    res.forEach((element:any) => {
      let subscriptions = element.subscriptions;
      subscriptions.forEach(subscription => {
        if(condition){
          this.populateData.push(subscription);   
        }
      });
      console.group('subscription list');
      console.log(this.populateData);
    });
  })
Sign up to request clarification or add additional context in comments.

4 Comments

Tried this but i am getting 'subscriptions' does not exist on type '{}', if i do console.log(element) data is there but there is icon i in console that says Values below are just evaluated now
try changing res.forEach(element... to res.forEach((element:any)...
subscriptions are coming after this change, is there a way to get data variable in res.forEach((element..
i found a workaround to get data in object in res.forEach. Thanks for solution

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.