0

I'm calling the service sending an array of ids as a parameter. In the function I need to do a foreach of this ids and make an api call for each one to get the full info of this element and after that do something with that info.

so how can I stop the execution of foreach until the end of the API call it has inside?

The function:

addCandidate(ids: any, candidate: string) {

    ids.forEach(elem => {

        this.getSearch(elem).subscribe(res => {

            let currentCandidates = res.candidates;
            if(currentCandidates) {
                if(!currentCandidates.includes(candidate)){
                    currentCandidates.push(candidate);
                    this.itemDoc.update({candidates: currentCandidates});
                }
            }else{
                this.itemDoc.update({candidates: [candidate]});
            }
        })

    });
}

Thanks!!

Nicolas Fabbro
  • 101
  • 1
  • 4
  • `Promise.all()` + `.map()` – Andreas Sep 04 '18 at 15:33
  • [https://stackoverflow.com/questions/29440632/how-to-block-for-a-javascript-promise-and-return-the-resolved-result#answers](https://stackoverflow.com/questions/29440632/how-to-block-for-a-javascript-promise-and-return-the-resolved-result#answers) – Verty00 Sep 04 '18 at 15:37
  • @Andreas how about async await? – brk Sep 04 '18 at 15:37
  • @Andreas Can you give an example of this solution implemented as the answer? – Verty00 Sep 04 '18 at 15:38
  • [.forEach()](https://stackoverflow.com/questions/2641347/how-to-short-circuit-array-foreach-like-calling-break) cannot be interupted, try [.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) instead. – zer00ne Sep 04 '18 at 15:52

2 Answers2

0

Here is an Example how to use promise and map.

let doSomthingToWaitFor = (ms) => {
  return new Promise(resolve => setTimeout(() => resolve('r-' + ms), ms))
}

(async (ids) => {
    await Promise.all(ids.map(async id => {
        let res = await doSomthingToWaitFor(id);
        console.log("my res: %s from id: %s", res, id);
    }));

    console.log("Successfully waited");
})([1000, 2000, 3000, 4000]);

You can implement your request in a function like doSomthingToWaitFor and handle the result afterwards.

0

It sounds like you want to map an array to a set of promises, and then wait for all that concurrent work to finish before doing something else.

I think you will find map, promise and async/await very helpful here, e.g.

const ids = [1, 2];

const work = await Promise.all(
  ids.map(ajaxCall)
);

// 'await' means that this won't be called until the Promise.all is finished
printToScreen(work);
Jimmy Breck-McKye
  • 2,923
  • 1
  • 22
  • 32