0

Right now i have this code

router.get('/export', function(req, res, next) {
var postData, eventData, messageData, userData

    Posts.list().then(data=> {

    var jsonOutput=JSON.stringify(data)
    postData=jsonOutput //this doesnt work
})
.catch(erro => res.status(500).send('error'))
Events.list().then(data=> {
    var jsonOutput=JSON.stringify(data)
    eventData=jsonOutput //this doesnt work
})
.catch(erro => res.status(500).send('error'))
Messages.list().then(data=> {
    var jsonOutput=JSON.stringify(data)
    messageData=jsonOutput //this doesnt work

})
.catch(erro => res.status(500).send('error'))
Users.list().then(data=> {
    var jsonOutput=JSON.stringify(data)
    userData=jsonOutput //this doesnt work
})
.catch(erro => res.status(500).send('error')) 


 //Then when all data from colections is retrieve i want to use the 4 variables that i created in the beggining
});

So basicly im trying to retrieve the data from my mongo database and then assign the results to that 4 variables that i create, but im not getting success.

For what i´ve been seeing i have to use async but im having some trouble doing it.

3 Answers 3

1

I don't like too much mrlanlee solution. This is a typical situation where using async / await can really make sense. Anyway, the Hugo's solution (the second one, with async await), even if it just works, will make the four queries in sequence, one after another to. If you want a clean, working and parallel solution, check this:

router.get('/export', async function(req, res, next) {
   let data
   try {
      data = await Promise.all([
         Posts.list(),
         Events.list(),
         Messages.list(),
         Users.list()
      ]);
   // at this point, data is an array. data[0] = Posts.list result, data[1] = Events.list result etc..
   res.status(200).json(data)
   } catch (e) {
    res.status(500).send('error');  
   }    
});
Sign up to request clarification or add additional context in comments.

Comments

1

The other answer from Sashi is on the right track but you will probably run into errors. Since your catch statement on each promise returns 500, if multiple errors are caught during the query, Express will not send an error or 500 each time, instead it will throw an error trying to. See below.

router.get('/export', function(req, res, next) {
  var postData, eventData, messageData, userData

  try {
    postData = Posts.list().then(data=> {
      return JSON.stringify(data);
    });
    eventData = Events.list().then(data=> {
      return JSON.stringify(data)
    });
    messageData = Messages.list().then(data=> {
      return JSON.stringify(data);
    })
    userData = Users.list().then(data=> {
      return JSON.stringify(data)
    });
  } catch (err) {
    // this should catch your errors on all 4 promises above
    return res.status(500).send('error')
  }

 // this part is optional, i wasn't sure if you were planning
 // on returning all the data back in an object

  const response = {
    postData,
    eventData,
    messageData,
    userData,
  };

  return res.status(200).send({ response })
});

For explanation of why you weren't able to mutate the variables, see Sashi's answer as he explains it.

1 Comment

You beat me to it :) @Hugo go with this method if you are not very comfortable using async/await
0

The variables defined outside the async code is out of scope of the async functions. Hence you cannot store the returned value from the async functions in those variables.

This should work.

router.get('/export', function(req, res, next) {
var postData, eventData, messageData, userData

    postData = Posts.list().then(data=> {

        var jsonOutput=JSON.stringify(data);
        return jsonOutput;
    }).catch(erro => res.status(500).send('error'));

    eventData = Events.list().then(data=> {
        var jsonOutput=JSON.stringify(data);
        return jsonOutput;
    }).catch(erro => res.status(500).send('error'));

    messageData = Messages.list().then(data=> {
        var jsonOutput=JSON.stringify(data);
        return jsonOutput;

    }).catch(erro => res.status(500).send('error'));

    userData = Users.list().then(data=> {
        var jsonOutput=JSON.stringify(data);
        return jsonOutput;
    }).catch(erro => res.status(500).send('error'));


});

Using Async/Await is a much neater solution.

router.get('/export', async function(req, res, next) {
var postData, eventData, messageData, userData;
try{
    postData = await Posts.list();
    eventData = await Events.list();
    messageData = await Messages.list()
    userData = await Users.list();
catch (e){
    res.status(500).send('error');  
}

});

3 Comments

if i do console.log(userData) after all that it displays [object Promise] instead of the json.
@Hugo that's because console.log often does not wait for the Promise to resolve, it logs it at it's current state. You can use async await magic here if you want. But this solution can run into issues because you CAN return res.status multiple times
Agree on the async await approach and the try catch

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.