0

I have looked at this question/answer but can't get it to work for my needs.

I have an async function in an offer.js file, which I need to call from a Controller file. The offer.js file works correctly and returns JSON data. It's the calling Controller file which I can't get to 'wait' for the data to come back before continuing with the rest of the page.

This is what the Controller file does:

var router = require('express').Router(); // Express.js router functionality
const Offer = require('../models/offer'); // the offer.js file which has getAllOffers() async function

// call/return the data from getAllOffers() async function
var rsOffersAll = async function() {
  return await Offer.getAllOffers(); 
}

// I would like rsOffersAll to have data before doing anything further at this point.

// if the homepage, supply the rsOffersAll data to the view.
router.get('/', function(req, res, next) {
  res.render('index', { data: rsOffersAll  });  // the data needs to be here. this should not run until the data is available to pass to the view
});

How do I ensure that var rsOffersAll has data before the router.get... stuff executes?

volume one
  • 6,800
  • 13
  • 67
  • 146
  • `router.get('/',` **async** `function(...) { ... { data:` **await** `rsOffersAll` **()** }); ...}); – blex Nov 17 '19 at 20:44

2 Answers2

3

rsOffersAll is redundant here, you await the result internally but you don't then await the result of rsOffersAll from the route handler.

router.get('/', async (req, res, next) => {
  const data = await Offers.getAllOffers();
  res.render('index', { data });
});
James
  • 80,725
  • 18
  • 167
  • 237
  • thanks for this. but what if I want to do this `res.render('index', { pagetitle: 'Homepage', metadesc: 'The site's homepage', data: rsOffersAll });` where I want to pass more parameters to the view than just the `data` ? – volume one Nov 17 '19 at 20:56
  • 1
    @volumeone just add them: `{ pagetitle: 'Homepage', /* ... */, data }` (but just keep `data`, don't do `data: rsOffersAll`) Just having `data` is equivalent to having `data: data`. – blex Nov 17 '19 at 21:08
  • 1
    @volumeone as blex has already explained, I've simply made use of [short-hand notation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer), if you need more properties then you simply add them like you would normally – James Nov 17 '19 at 21:48
  • if I do this `router.get('/', async (req, res, next) => { const data = await Offers.getAllOffers(); console.dir(data); res.render('index', { data }); });` How come `data` never prints to the console? – volume one Nov 17 '19 at 23:23
  • `console.dir` prints an object properties, presumable `data` is an array? Try just `console.log` – James Nov 17 '19 at 23:54
  • If I run `(async function () { var data = await Offer.getAllOffers(); console.dir(data); })();` then I get the `data` in the console fine as a JSON string. When I run it in the router like in your answer, it hangs for ages and then I get an error saying "Database is already connected! Call close before connecting to different database." Should I ask a new question about this? – volume one Nov 18 '19 at 00:07
  • 1
    @volumeone yes, you would appear to be opening a global connection and not closing therefore when another request comes in it hangs – James Nov 18 '19 at 08:35
  • I have closed the connection properly and that error has gone away. But the code still won't run when I place it inside the `router.get()`. I now get an login failure with my database, but I get no such failure if do `(async function () { var data = await Offer.getAllOffers(); console.dir(data); })();` outside of `router.get()`. Any idea what might be causing that? – volume one Nov 18 '19 at 13:03
  • @volumeone sorry these questions are way off-topic now, and clearly related to your DB setup. I would advise you open up a new question for that. – James Nov 18 '19 at 13:18
0

rsOffersAll is async and it will return a promise so you can use then

 router.get('/', function(req, res, next) {

    rsOffersAll().then((res) = >{
        res.render('index', { data: res  });
    });

});
Saurabh Yadav
  • 3,303
  • 1
  • 10
  • 20