manipulate 2 redis hgetall queries into a single response

Viewed 34

Below is my current working code, but now i need to aggregate the values from 2 separate redis keys into 1 response.

function resolveEnergyProBusDeviceInfo(req: any, res: any) {
  const uuid = req.params.uuid
  const key = "stream-api-uuid." + uuid + ".devInfo"
  client.hgetall(key, function (err, data) {
    if (err) {
      throw err;
    }
    if (data !== null) {
      const devInfo: devInfo = JSON.parse(JSON.stringify(data))

      return res.status(200).json({
        "uuid": JSON.parse(String(devInfo.uuid)),
        "bus_index": parseInt(String(devInfo.bus_index)),
        "sensors": JSON.parse(String(devInfo.sensor))
      });
    } else {
      return res.status(204).send();
    }
  });
}

so i'm trying to do something like the below (apologies im still in the synchronous mindset):

function resolveEnergyProBusDeviceInfo2(req: any, res: any) {

  const uuid = req.params.uuid
  const key0 = "stream-api-uuid." + uuid + ".0.devInfo"
  const key1 = "stream-api-uuid." + uuid + ".1.devInfo"

  const bus0Info = queryDevInfoForIndex(key0);
  const bus1Info = queryDevInfoForIndex(key1);

  return res.status(200).json({
    "uuid": uuid,
    "bus_info0": JSON.parse(String(bus0Info)),
    "bus_info1": JSON.parse(String(bus1Info))
  });
}

function queryDevInfoForIndex(key: string) {
  client.hgetall(key, function (err, data) {
    if (err) {
      throw err;
    }
    if (data !== null) {
      const busInfo: devInfo = JSON.parse(JSON.stringify(data))
      return busInfo;
    } else
    const busInfo: devInfo = JSON.parse(JSON.stringify(data))
    return busInfo;
  })
}

Because hgetall returns a boolean, and it's data can seemingly only be manipulated within its callback, im having trouble constructing the response on a higher level. Was looking into promises but didn't get too far yet...

1 Answers

This is the meat of my solution, after some experimentation, using:

  • Promisified the redis hgetall call
  • async/await to store the value
const client = redis.createClient({
  host: config.get('redis.host') as string,
  port: config.get('redis.port') as number
});

const pClient = bluebird.promisifyAll(client);

async function getBusInfo(key: String) {
  return pClient.hgetallAsync(key)
    .then((data: any) => {
      if (!_.isEmpty(data)) {
        const parsedData = JSON.parse(JSON.stringify(data))
        let parsedBusInfo = {} as BusInfo;
        parsedBusInfo.bus_index = parseInt(String(parsedData.bus_index));
        parsedBusInfo.sensor = JSON.parse(String(parsedData.sensor));
        return parsedBusInfo
      } else {
        return {
          "anEmptyList": []
        }
      }
    })
    .catch((err: any) => {
      console.log(err);
    })
}

const bus0Info = await getBusInfo("myKey")
...
//parse and send back response
...

Related