Node_Redis HGET resolving to boolean array when using Promise.all

739 Views Asked by At

I've been digging into redis and working on a tiny webapp that uses redis as it's only data storage (I know it's not the intended purpose of redis but I am benefitting from learning the commands and just overall working with redis on Node. I'm using Node_Redis.

Here's what I want to accomplish (all in redis): I am try to retrieve the users using their emails.

Here's the problem: I have a Promise.all call which takes all emails (keys) and maps each to go a HGET command. When the Promise.all resolves I expect it to resolve with an array of user objects, but it ends up resolving to an array of booleans (i.e. [true, true, true]).

Here is the logic for /users

router.get("/", (req, res) => {
  client.lrange("emails", 0, 1, (err, reply) => {
    if (err) return console.log(err);
    if (reply) {
      Promise.all(
        reply.map(email => {
          return client.hgetall(email, (err, reply) => {
            if (err) return console.log(err);
            console.log("reply for hgetall", reply); // this prints a user object correct, but Promise.all still resolves to boolean array :(
            return reply;
          });
        })
      )
        .then(replies => {
          // replies = [true, true, true ...]
          res.send(replies);
        })
        .catch(e => console.log(e));
    } else {
      res.send([reply, "reply is null"]);
    }
  });
});

I've actually used Promise.all plenty of times, and when I log the reply from redis, it shows the correct object too, so I'm pretty confused at this point. How can I get Promise.all to resolve to an array of User objects?

1

There are 1 best solutions below

0
On BEST ANSWER

The problem is that client.hgetall doesn't return a promise. It's async function and you pass a callback to get a result. You should promisify this function to use it in Promise.all:

...
return new Promise((resolve, reject) => {
  client.hgetall(email, (err, reply) => {
    if (err) {
      return reject(err);
    }
    resolve(reply);
  });
});

You can do promisification manually (as in example above) or can use Bluebird or Q libraries with their promisify and promisifyAll methods.