Jens Törnell
Jens Törnell

Reputation: 24768

Set arguments dynamically with Promise.all().then()

The code below works for me

Promise.all([first, second, third]).then([first, second, third] => {
  console.log(second);
});

I know that console.log(second) will give me the value with the key second.

My promises are dynamically set and now it looks like below:

let collection = [second, third];

Promise.all(collection).then((collection) => {
  console.log(collection);
});

Question

How can I, like my first example, have something like named dynamically arguments like collection['second'] or similar?

Upvotes: 0

Views: 545

Answers (2)

Richard
Richard

Reputation: 7433

As we want to access the value dynamically, set collection to an empty object first. Then, use the keys from collection to pass all its Promise-values to Promise.all. Then, map back the fulfilled values and then, we can access collection's value by some key.

let collection = {}

for (let i = 0; i < 3; i++) {
  collection[`key${i}`] = Promise.resolve(i)
}

let collectionKeys = Object.keys(collection)
Promise.all(collectionKeys.map(key => collection[key]))
  .then(values => {
    let collectionFulfilled = collectionKeys.reduce((obj, key, i) => {
      obj[key] = values[i]
      return obj
    }, {})
    console.log(collectionFulfilled)
  })

Upvotes: 2

Keith
Keith

Reputation: 24181

If you pass your promises embedded inside an object with a single key, you could use that for it's name, and then with a simple helper function reverse the values & keys from this.

With the new ES6 you can then just pass like -> [{one}, {two}, {three}] etc.

Below is an example with a helper function called namedPromiseAll.

function namedPromiseAll(named) {
  const pcollection =
    named.map(m => Object.values(m)[0]);
  const ncollection =
    named.map(m => Object.keys(m)[0]);
  return Promise.all(pcollection).then((c) => {
    return c.reduce((a,v,ix) => {
      a[ncollection[ix]] = v;
      return a;
    }, {});
  });
}


const second = Promise.resolve(2);
const third = Promise.resolve(3);

const collection = [{second}, {third}];

namedPromiseAll(collection).then(console.log);

Upvotes: 1

Related Questions