Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async await in Express middleware not working

I'm a bit of newbie to Node so be gentle. I'm creating an app for my wedding which takes an uploaded guestlist (in Excel file format) and turns it into a JSON array which I can then use to build profiles about each guest (dietary requirements, rsvp answer, etc).

So far I've got a form on the homepage which allows the user to upload the .xlsx file and when the form is submitted the user is redirected back to the homepage again.

I've created the following route:

router.post('/',
    guestsController.upload,
    guestsController.getGuestlist,
    guestsController.displayGuestlist
);

and here's my guestsController:

const multer = require('multer');
const convertExcel = require('excel-as-json').processFile;

const storage = multer.diskStorage({ //multers disk storage settings
    destination: function (req, file, cb) {
      cb(null, './uploads/')
    },
    filename: function (req, file, cb) {
        var datetimestamp = Date.now();
        cb(null, file.fieldname + '-' + datetimestamp + '.' + file.originalname.split('.')[file.originalname.split('.').length -1])
    }
});

exports.upload = multer({storage: storage}).single('file');

exports.getGuestlist = async (req, res, next) => {

  try {
     await convertExcel(req.file.path, null, null, (err, guestData) => {
         req.guestlist = guestData.map((guestObj) => Object.values(guestObj)[0]);
     });
     console.log(req.guestlist);
     next();
  } catch (e){
    res.json({error_code:1,err_desc:"Corrupted Excel file"});
    next();
  }
};

exports.displayGuestlist = (req, res) => {
    console.log(req.guestlist);
};

At the moment because of the synchronous nature of the functions, displayGuestlist is returning undefined to the console because covertExcel has not finished grabbing the data. You can see I have tried to use the new async await syntax to resolve this but it hasn't fixed it unfortunately.

I have also tried putting the log in displayGuestlist in a timeout function which has proven that this is purely a timing issue.

Any helpers would be much appreciated.

like image 966
James Howell Avatar asked Oct 16 '25 20:10

James Howell


1 Answers

It looks like convertExcel is not a Promise-returning function, but rather uses an old-school callback. await does not work with those, so it's instead awaiting Promise.resolve(undefined) since the function returns undefined, not a Promise. Thankfully, in Node 8 and later, there's a promisify utility to convert callback-style functions to Promise-returning functions so that await can be used.

const { promisify } = require('util');
const convertExcel = promisify(require('excel-as-json').processFile);

// ...

const guestData = await convertExcel(req.file.path, null, null);
req.guestlist = guestData.map((guestObj) => Object.values(guestObj)[0]);
like image 183
Jacob Avatar answered Oct 18 '25 08:10

Jacob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!