0

I'm new in JS and I don't know hot to achieve this. I have a JS object like this:

{ 'U9B6QVB9B': 26, 'U2B2HKB5H': 23, 'U4Q7S4JTB': 41 }

I want to apply a async function from Slack API to each key (which represent the ID of a Slack user), in order to obtain the user's name. The first try was something like this:

    var userIdToName = function(cuenta){

      var cuentaF = {};
      for (var key in cuenta){

      slack.users.info({token, key}, function(err, data){        
          var nombre = data.user.name;
          cuentaF[nombre] = cuenta[key];
        })
      }
     return cuentaF;

    }

But now, I know that it isn't possible because 'var key' changes its value and the loop ends before the first async call ends. I have been reading about Promises and other JS and Node tools, but I until the moment I haven't been able to imagine how to use them to achieve it.

Thanks in advance.

Note: I'm using NodeJS v4.6.0, but I could change it to another version if it would be necessary.

p0kero
  • 120
  • 1
  • 1
  • 12
  • what does token,key means? Its not valid syntax – Rahul Arora Jul 08 '17 at 17:17
  • key is the iterative variable used in the "for-in" loop, which is the key of each pair of the object. token is a global variable used to connect to the Slack bot. And the syntax is because I'm using this package: https://www.npmjs.com/package/slack – p0kero Jul 08 '17 at 17:27

1 Answers1

1

If you can get slack.users.info to return a promise, you can do this:

const promises = Object.keys(cuenta)
  .map(key => slack.users.info({ token, key });

Promise.all(promises)
  // turn promises back into object 
  .then(results => results.reduce(
    (cuentaF, currentResult, i) => Object.assign({}, cuentaF, {
      [Object.keys(cuenta)[i]]: currentResult
    }),
    // starting point
    {}
  ))

If slack won't give you promises you could make your own function that returned a promise like this

 function getSlackInfo(key) {
   return new Promise((resolve, reject) => slack.users.info({ token, key }, (err, result) => {
     if (err) { reject(err); }
     else { resolve(result); }
   })
 }
Zeke Nierenberg
  • 2,216
  • 1
  • 19
  • 30
  • This is probably what I need, so thanks a lot. But I'm a bit confused about the 'then' part. Could you give me a little explanation about what it does? Where or how should I use the final object 'cuentaF'? Thanks again! – p0kero Jul 08 '17 at 18:09
  • Every promise has a `.then` method. It basically let's you access the result of some async operation. It also allows you to pass around the promise in the mean time. The promise is like a movie ticket. It isn't the movie itself, just a commitment to let you watch the movie. To get the movie, you need `.then` – Zeke Nierenberg Jul 08 '17 at 18:21
  • To get `cuentaF` you'd add another `.then` to the chain like this: `.then(result => dowhatever(result));` – Zeke Nierenberg Jul 08 '17 at 18:22
  • That is!! Thank you very much!! :D – p0kero Jul 09 '17 at 09:05