Search code examples
javascriptnode.jsasync-awaitfile-read

Javascript async/await : undefined error on file read


I am trying to send the email with for loop using async/await.

const prepareNotification =(genie)=>{
    genie.forEach(async (item)=>{
        if(item.is_active){

            if(item.is_email){
                sendEmailNotification(item);
            }

        }else{
            console.log('deal genie inactive for',item.name);
        }
    });
}

For sending, I need to read the HTML from a file and send to the mail function.

const sendEmailNotification=async (item)=>{
    try{

        let emailTemplate = await fs.readFile(__basedir+'/controllers/html/sharedeal.html','utf-8');
        console.log(emailTemplate);
        let replacements = {
            dealLink:'testlinkhere'
           };
        let mailOptions = {
                   from: process.env.smtpEmail,
                   to: item.email,
                   subject: 'DealLink',
                   replacements:replacements,
                   template:emailTemplate
           };
        let mail = await sendEmail(mailOptions);
    }catch(error){
      console.log(error);
   }
}

but I am getting undefined on console.log(emailTemplate);, one more question how can i make sure that the sendEmailNotification is execute one after another on each state in the for loop??


Solution

  • fs.readFile doesn't support async/await. But you can create a version that does:

    const util = require('util');
    const readFileAsync = util.promisify(fs.readFile);
    

    and then

    let emailTemplate = await readFileAsync(__basedir+'/controllers/html/sharedeal.html','utf-8');
    console.log(emailTemplate);
    

    how can i make sure that the sendEmailNotification is execute one after another on each state in the for loop??

    const prepareNotification = async (genie) => {
        for (let item of genie) {
            if(item.is_active){
    
                if(item.is_email){
                    await sendEmailNotification(item);
                }
    
            }else{
                console.log('deal genie inactive for', item.name);
            }
        }
    }
    

    or

    const prepareNotification = (genie) => {
        genie.reduce((prev, item) => {
            if(item.is_active){
    
                if(item.is_email){
                    return prev.then(() => sendEmailNotification(item));
                }
    
            }else{
                console.log('deal genie inactive for', item.name);
            }
            return prev;
        }, Promise.resolve());
    }