Search code examples
node.jsexpressaxiosnodemailer

async method chaining in express.js


i couldnt async chaining in expressjs. The first method(getUser) is working fine and returns value properly. The second method (sendmail) is working fine (mail is sent) but it returns always undefined. mailResponse value in app.js always returns undefined.

If it wasn't running, the inside of the method shouldn't have worked either, but everything works fine except return statement. What is the wrong part?

this is my axios method;

const axios = require('axios');

const getUser = async (id) => {
    try {
        const response = await axios.get('xxxxxx', {
          params: {
            id: id
          }
        });
        return response.data[0];
    } catch (err) {
        console.log(err);
    }
}

module.exports = getUser;

sendmail method;

var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: 'youremail@gmail.com',
    pass: 'yourpassword'
  }
});

var mailOptions = {
  from: 'youremail@gmail.com',
  to: 'myfriend@yahoo.com',
  subject: 'Sending Email using Node.js',
  text: 'That was easy!'
};

const sendMail = async (data) => {
    email.send(mailOptions).then(() =>{         
        console.log("email has been sent!");
        return true;
      }).catch((err) => {
        console.log(err)
        return false;
      });
}

module.exports = sendMail;

app.js

const express = require('express');
const app = express();
const port = 3000;
const getUser = require('./fetchData');
const sendMail = require('./sendMail');
let userid = '';
let fetchedData = null;

app.get('/', (req, res) => {
    res.send('server is running');
});

app.listen(port, () => {
    console.log('App is listening');
});

app.get('/send', (req, res) => {
    userid = req.query.userid;
    
    if(!userid){
        res.status(404).send('Sorry, cant find that');
    } else {
       getUser(userid).then(axiosResponse => {
            console.log("axiosResponse => ", axiosResponse);
            fetchedData = axiosResponse;
            
            sendMail(fetchedData);
            
        }).then(mailResponse => {
            console.log("express mail response => ", mailResponse);
            res.send(mailResponse);
        });
    }
});

Solution

  • The biggest issue I can see from your existing code is you're not returning anything in your then methods. That being said, I think you'll gain a lot my clarity by consistently using async/await rather than mixing it with Promise syntax:

    // sendMail rewrite
    const sendMail = async (data) => {
      try {
        await email.send(mailOptions);
        return true;
      } catch(err) {
        console.log(err);
        return false;
      }  
    }
    
    // get 'send' rewrite
    app.get('/send', async (req, res) => {
      const userid = req.query.userid;
      
      if (!userid) {
        res.status(404).send('Sorry, cant find that');
        return;
      }
      
      try {
        const axiosResponse = await getUser(userid);
        console.log("axiosResponse => ", axiosResponse);
        const mailResponse = await sendMail(axiosResponse);
        console.log("express mail response => ", mailResponse);
        res.send(mailResponse);
      } catch(err) {
        // Do something with any errors here
      }
    });