0

I have this issue in nodeJS where the code below the call to 4 async functions is executed before the functions return any data. The code below should return the status of each call in json. How can I execute each function in sequence? So when I return the data to caller its with the updated status or error that happened in each function?

This is what i have now..

let idItem = "";
    let statusInsert = "N/A";
    let statusSms = "N/A";
    let statusEmail = "N/A";
    let msgErro = "N/A";


    try {

        let retorno = inserirEmergencia(req).then(
        iar => {
            console.log(iar);
            idItem = iar.data.ID;
            statusInsert = "OK";
        }
        );  

      } catch (e) {
        //Error handling
        idItem = "0";
        statusInsert = "Erro";
        msgErro += " > " + e.message;
      }

      let jsonResposta = 
      {
          "idItem" : idItem,
          "statusInsert" : statusInsert,
          "statusSms" : statusSms,
          "statusEmail" : statusEmail,
          "msgErro" : msgErro
      }

      res.json(jsonResposta);

so, jsonResposta has the initial values, how can i execute four functions like that and be sure that at the end the value is the actual function returns?

3
  • 1
    Show what you've done so far and where the problem is exactly. Commented Feb 21, 2020 at 17:30
  • this is the code i have right now, i edited the post. Commented Feb 21, 2020 at 18:35
  • Look into async/await since it looks like you're using Promises (inserirEmergencia(req).then). This answer is actually quite close to what you're looking for - stackoverflow.com/a/60243171/5862900 or this stackoverflow.com/a/57486730/5862900 Commented Feb 21, 2020 at 20:17

3 Answers 3

3

As you are probably aware, things run asynchronously in node.js. So when you need to get things to run in a certain order you need to make use of a control library or basically implement it yourself.

I suggest you to take a look at the following concepts:

1) Callback functions.

2) async and await

With these, you can control the flow of execution.

Sign up to request clarification or add additional context in comments.

Comments

1

You cannot try/catch an exception from a Promise unless you put it inside an async function and await it.

This how you construct this flow using the Promise outcome:

let idItem = "";
    let statusInsert = "N/A";
    let statusSms = "N/A";
    let statusEmail = "N/A";
    let msgErro = "N/A";

    inserirEmergencia(req)
    .then(iar => {
       idItem = iar.data.ID;
       statusInsert = "OK";
     })
     .catch(e => {
        idItem = "0";
        statusInsert = "Erro";
        msgErro += " > " + e.message;
     })
     .then(() => res.json({
          "idItem" : idItem,
          "statusInsert" : statusInsert,
          "statusSms" : statusSms,
          "statusEmail" : statusEmail,
          "msgErro" : msgErro
      }))

Here is another way, with a different approach to the data. You are "transforming a default data object based on a response, then passing it to a res.json call", so you can do this:

const defaults = {
  idItem: "0",
  statusInsert: "N/A",
  statusSms: "N/A",
  statusEmail: "N/A",
  msgErro: "N/A"
}

inserirEmergencia(req)
    .then(iar => ({
       ...defaults,
       idItem: iar.data.ID,
       statusInsert: "OK"
     })
     .catch(e => ({
        ...defaults,
        statusInsert: "Error",
        msgErro: ` > ${e.message}`
     })
     .then(res.json)

Here is how you do it with async/await:

post('/emergencia', async (req, res) => {
   const defaults = {
     idItem: "0",
     statusInsert: "N/A",
     statusSms: "N/A",
     statusEmail: "N/A",
     msgErro: "N/A"
   }
   try {
      const iar = await inserirEmergencia(req)
      return res.json({
         ...defaults,
          idItem: iar.data.ID,
          statusInsert: "OK"
      })
   } catch (e) {
      return res.json({
         ...defaults,
         statusInsert: "Error",
         msgErro: ` > ${e.message}`
      })
   }
}

You can compress this further by inlining the call to inserirEmergencia:

post('/emergencia', async (req, res) => {
   const defaults = {
     idItem: "0",
     statusInsert: "N/A",
     statusSms: "N/A",
     statusEmail: "N/A",
     msgErro: "N/A"
   }
   try {
      return res.json({
         ...defaults,
          idItem: (await inserirEmergencia(req)).data.ID,
          statusInsert: "OK"
      })
   } catch (e) {
      return res.json({
         ...defaults,
         statusInsert: "Error",
         msgErro: ` > ${e.message}`
      })
   }
}

The last one obscures the side-input, which doesn't help maintainers - including you in the future. It's not too bad, but you are mixing data transformation there with an API call, so I wouldn't do it. Just including it so you have more information about what is possible as you learn async in JS.

Comments

0

Each async function returns a promise, so to prevent the non blocking code to execute you can place that code after the promise resolves. i.e. by calling the callback function of .then, or simply awaiting for the promise to resolve and then doing the task.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.