3
votes

I easily accomplished this with the fs.readFileSync but I want to do this asynchronously. My code follows.

    function send(err, str){

        if(err){
            console.log(err);
        }

        var template = ejs.render(str, 'utf8', {name: data.name});

        transporter.sendMail({
            from: myEmail,
            to: anotherEmail,
            subject: mySubject,
            html: template,
            attachments: images
        }, function(err, response) {
            if(err){
                console.log(err);
            }
        });
    }

    fs.readFile('emailTemplate.ejs', send);

So I made my own callback for fs.readFile so that when the file has been read it will render the email, putting the proper name in and then send it off with nodemailer. However, it does not like this. It gets by the error if no problem but render throws the following error when it tries to render the template.

TypeError: Object (Followed by the entire HTML of the template) has no method 'indexOf' at Object.exports.parse (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:144:21) at exports.compile (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:229:15) at Object.exports.render (/home/ubuntu/workspace/node_modules/ejs/lib/ejs.js:289:10) at send (/home/ubuntu/workspace/routes/email.js:171:28) at fs.readFile (fs.js:272:14) at Object.oncomplete (fs.js:108:15)

Doing it synchronously works fine though.

    var str = fs.readFileSync('emailTemplate.ejs', 'utf8');

    var template = ejs.render(str, {
        name: data.name
    });

Can anyone give me any insight into why this is happening?

2

2 Answers

1
votes

The documentation of fs.readFile and fs.readFileSync says

If no encoding is specified, then the raw buffer is returned.

Because you provide the encoding with the synchronous version, but do not with the asynchronous one they both differ in behaviour.

If you try this:

fs.readFile('emailTemplate.ejs', {encoding: "utf8"}, send);

it should work.

0
votes

Try setting the encoding of the fs.readFile call, e.g.:

fs.readFile('emailTemplate.ejs', 'utf8', send);

When calling readFile asynchronously there is no default encoding, and instead returns the raw buffer. Currently, this buffer is being sent to the EJS render call and failing.

See the node documentation for readFile for more information.