Search code examples
javascriptnode.jsarrayspromisehttpresponse

Using array of functions in node.js works fine, but the await does not wait?


I am attempting to use an array of functions to execute the appropriate function based on a passed in value:

const functions = {
  VALUE_1: async function (body, context) {
    await alertEventService.receivedValue1(body, context)
  },
  VALUE_2: async function (body, context) {
    await alertEventService.receivedValue2(body, context)
  },
  VALUE_3: async function (body, context) {
    await alertEventService.receivedValue3(body, context)
  },
  VALUE_4: async function (body, context) {
    await alertEventService.receivedValue4(body, context)
  },
}

I am calling the function like this:

router.post('/system/', auth.required, async function (req, res) {
      try {
        let response_def = await functions[`${req.body.event_type}`](req.body, req.context) // This await does not seem to wait! 
        if (response_def) {
          res.status(response_def)
        } else {
          res.status(400).send(`Something went wrong with the system message`)
        }
      } catch (error) {
        log.error(error)
        res.status(500).send(error)
      }
})

The problem is that response_def is always undefined when it gets to the if statement, and so the code always returns a status 400 even though the request succeeded.

I have carefully checked all of the code in the called function and everything is threaded properly.

Besides not awaiting, everything works just fine. I am returning a 204 from the called function.

Any ideas would be greatly appreciated. I don't want to use switch!


Solution

  • response_def is undefined because you don't return anything.

    You should instead write this

    const functions = {
      VALUE_1: async function (body, context) {
        return await alertEventService.receivedValue1(body, context)
      },
      VALUE_2: async function (body, context) {
        return await alertEventService.receivedValue2(body, context)
      },
      VALUE_3: async function (body, context) {
        return await alertEventService.receivedValue3(body, context)
      },
      VALUE_4: async function (body, context) {
        return await alertEventService.receivedValue4(body, context)
      },
    }
    

    note that the last await is not necessary, and neither is the async, this should work too but it less explicit

    const functions = {
      VALUE_1(body, context) {
        return alertEventService.receivedValue1(body, context)
      },
      VALUE_2(body, context) {
        return alertEventService.receivedValue2(body, context)
      },
      VALUE_3(body, context) {
        return alertEventService.receivedValue3(body, context)
      },
      VALUE_4(body, context) {
        return alertEventService.receivedValue4(body, context)
      },
    }