Search code examples
angulartypescriptes6-promise

Promise.all not working as expected with array


Here is my code, I start with an empty array and want to call a service that does some work with the populated array. I populate the array using two calls to services which call an API to receive elements to insert into the array.

I am trying to use promises to ensure that my array subscribers is full of the proper subscriber objects, but the method processSubscribers always receives an empty array even though objects do eventually get added to the subscribers array (as seen in chrome debugging).

doSomething(){
    const subscribers: ISubscriber[] = [];
    const promises = [];

    this.selectedChildren.forEach(child => {
        promises.push(this.serviceA.getSubscribers(child.id).subscribe( (subs: ISubscriber[]) => {
            subs.forEach(s => {
                subscribers.push(s);
            });
        }));
    });

    this.selectedSubscribers.forEach(sub => {
        promises.push(this.serviceB.getSubscriber(sub.subscriberId).subscribe( (sub: ISubscriber) => {
            subscribers.push(sub);
        }));
    });

    // subscribers is always empty when this call is made 
    // since above code hasn't finished executing
    Promise.all(promises).then( a => {
        this.serviceC.processSubscribers(this.id, subscribers).subscribe( id => {
            this.toastr.success('Success!');
        });
    });
}

Solution

  • The result of this line of code is a subscription not a promise

    this.serviceA.getSubscribers(child.id).subscribe( (subs: ISubscriber[]) => {
                subs.forEach(s => {
                    subscribers.push(s);
                })
    

    It means your promise array doesn't include promises and this is why promise.all doesn't work

    You can do this

    promises.push(this.serviceB.getSubscriber(sub.subscriberId).toPromise())

    or

    promises.push(this.serviceB.getSubscriber(sub.subscriberId).toPromise().then(x => ... ))