0

I have an object with two arrays as properties:

I want to populate the arrays by running promises in series. I fetch the result of the promises, and map a function to decorate all the items in my arrays.

While one array get populated and persist, the other get populated only while in the map function, but at the end the array is returned still empty.

Can you help to understand why?

I check the Promise is actually returned, and indeed in one case it works, not in the other.

this is my pseudo-code:

function formatMyObject( arrayOfIds ) {

// initialize the objet
var myObj = {
   decorators = [],
   nodes = []
   ...
}

// I map the Promise reconciliate() and push the results in the array:

return reconciliateNode(arrayOfIds)
       .then( data => { 
             data.map( node => {
                //  I fetch results, and   myObj.nodes

             myObj.nodes.push( { ...   })
            })

       })

     return myObj
    })
   .then( myObj => {

      // myObj.nodes is now a NON empty array

      // I want to the same with myObj.decorators:

      var data = myObj.nodes

      // I think I am doing just as above:

      data.map( node => 
          decorateNode(node.source)
            .then( decoration => {

              decoration = decoration[node.source]

              myObj['decorators'].push( {
                    ... 
              } )

              // I check: the array is NOT empty and getting populated:
              console.log('myObj.decorators', myObj)
              debugger
          })
    )

    // instead now, just after the map() function, myObj.decorators is EMPTY!
    console.log('myObj.decorators', myObj);
    debugger


    return myObj
)

... // other stuff
}
user305883
  • 1,635
  • 2
  • 24
  • 48
  • 1
    Because the remaining portion of `formatMyObject()` runs before the promise has completed. – Kramb Feb 08 '19 at 21:18
  • 1
    Could you please fix the indentation and the unbalanced braces in your code? It is not entirely clear how you really have it. – trincot Feb 08 '19 at 21:20
  • See [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/); [Why is value undefined at .then() chained to Promise?](https://stackoverflow.com/questions/44439596/). _"I want to populate the arrays by running promises in series."_ What do you mean by _"in series"_? – guest271314 Feb 08 '19 at 21:26
  • _"if you think I need to amend the title to make it clearer or more exhaustive, please let me understand better your suggestion."_ Yes, can you include what you mean by _"in series"_ in the question? – guest271314 Feb 09 '19 at 17:17

1 Answers1

1

As in the second case the map callback returns a promise, that case is quite different from the first case.

In the second case, you would need to await all those promises, for which you can use Promise.all.

The code for the second part could look like this:

.then( myObj => {
    return Promise.all(myObj.nodes.map(node => decorateNode(node.source)));
}).then(decorations => {
    myObj.decorators = decorations.map(decoration => {
        decoration = decoration[node.source];
        return ({
            ... 
        });
    })
    console.log('myObj.decorators', myObj);
    return myObj;
})
trincot
  • 317,000
  • 35
  • 244
  • 286
  • Is _"in series"_ at the question omitted from being addressed at the answer for lack of clarity as to what that term means at the actual question? – guest271314 Feb 08 '19 at 21:50
  • @guest271314, I took this to refer to the two phases the OP has, which indeed are chained -- no problem with that. I understood the question not to be about that aspect, but about: *"at the end the array is returned still empty. ...why?"* -- also reflected in the title *"...does not persist"* – trincot Feb 08 '19 at 21:55
  • Interesting perspective that had not considered. – guest271314 Feb 08 '19 at 21:58
  • @trincot I marked as correct because it works and i understand I have to wait for all the promises, but not clear that, when I ` // I check: the array is NOT empty and getting populated: console.log('myObj.decorators', myObj)`while being in the map function, I see that `myObj.decorators` is not empty, while outside of the `map`function it is. Why the map object is returned to the next `then()`and does not keep reference to the array property that is being populated ? - hope I was clear to let you understand my question. – user305883 Feb 09 '19 at 17:13
  • @guest271314 if you think I need to amend the title to make it clearer or more exhaustive, please let me understand better your suggestion. – user305883 Feb 09 '19 at 17:14