HuseyinUslu
HuseyinUslu

Reputation: 4134

Promise.map over object

I've an object like;

{ '6': { stream: { twitch: [Object] } },
  '7': { stream: { twitch: [Object] } },
  '8': { stream: { twitch: [Object] } },
  '9': { stream: { twitch: [Object] } },
  '10': { stream: { twitch: [Object] } },
  '11': { stream: { twitch: [Object] } } }

I want to iterate over it like;

return Promise.map(myObj, function(minute, minuteIndex) {

so basically minute should hold the data and minuteIndex should be holding the index.

I can do it with lodash but bluebird can't somehow.

_.forEach(hour.minutes, function(minute, minuteIndex) {

I know that this code was working before but now can't get it so.

Any ideas?

Upvotes: 4

Views: 20662

Answers (4)

RepiatX
RepiatX

Reputation: 105

Promise.all(

  Object.keys(twitchStats).map(key => Promise.resolve({
        minute: key, minuteIndex: twitchStats[key]
    })

)

Use combination of Promise.all() with map() functions. Be careful: map() has to return promise in order for Promise.all() work.

Upvotes: 2

MrMaz
MrMaz

Reputation: 31

You don't specify in your question if you are using the Promise.map() callback to return a promise or a value. If you only want to return a value, there is not much benefit to using Promise.map() over forEach.

Bluebird's Promise.map() used for it's most basic interface is according to the docs:

to replace the .push+Promise.all boilerplate

Assuming you want to return promises, you can use lodash.map() to iterate over the object and have the key available when creating the promise, then use Promise.all() to execute them.

  let jobs =
    _.map(myObj, (minute, minuteIndex) => {
      return fnThatReturnsPromise(minute, minuteIndex);
    });

  return Promise.all(jobs);

Or as a single statement that more closely resembles your desired format

  return Promise.all(_.map(myObj, (minute, minuteIndex) => {
    return fnThatReturnsPromise(minute, minuteIndex);
  }));

Upvotes: 0

alexvicegrab
alexvicegrab

Reputation: 531

You can also convert the object to an array, using _.toPairs, then you should be able to use the Promise.map methods.

Upvotes: 0

Tomalak
Tomalak

Reputation: 338148

You can map the object's keys into an array and give that to Promise.map():

function process(stats) {
    var statsArray = Object.keys(stats).map(key => ({
        minute: key, minuteIndex: stats[key]
    }));
    return Promise.map(statsArray, item => {
        // work with item.minute & item.minuteIndex
    });
}

Usage:

var twitchStats = {
  '6': { stream: { twitch: [Object] } },
  '7': { stream: { twitch: [Object] } },
  '8': { stream: { twitch: [Object] } },
  '9': { stream: { twitch: [Object] } },
  '10': { stream: { twitch: [Object] } },
  '11': { stream: { twitch: [Object] } }
};

process(twitchStats).then(result => {
    // ...
});

Upvotes: 5

Related Questions