Keystone-classic: TypeError: this.templateEngine.compile is not a function

Created on 5 Dec 2016  ·  10Comments  ·  Source: keystonejs/keystone-classic

Steps to reproduce the behavior

use handlebars

package.json :
"express-handlebars": "^3.0.0",
"handlebars": "^4.0.5",
"keystone": "^0.3.16",

Fill up the contact form and submit.

Expected behavior

form submits

Actual behavior

GET /contact 304 562.975 ms
TypeError: this.templateEngine.compile is not a function
at null. (/home/aaa/bb/my-site/node_modules/keystone/lib/email.js:347:35)
at null. (/home/aaa/bb/my-site/node_modules/keystone/lib/email.js:318:11)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:380:3)

Most helpful comment

@marvinworks Thank you for your help.
However i found another solution too, using mailgun and keystone-email.

Please find the update Enquiry.js

var keystone = require('keystone');
var Types = keystone.Field.Types;
var Email = require('keystone-email');

/**
 * Enquiry Model
 * =============
 */

var Enquiry = new keystone.List('Enquiry', {
    nocreate: true,
    noedit: true,
});

Enquiry.add({
    name: { type: Types.Name, required: true },
    email: { type: Types.Email, required: true },
    phone: { type: String },
    enquiryType: { type: Types.Select, options: [
        { value: 'message', label: 'Just leaving a message' },
        { value: 'question', label: 'I\'ve got a question' },
        { value: 'other', label: 'Something else...' },
    ] },
    message: { type: Types.Markdown, required: true },
    createdAt: { type: Date, default: Date.now },
});

Enquiry.schema.pre('save', function (next) {
    this.wasNew = this.isNew;
    next();
});

Enquiry.schema.post('save', function () {
    if (this.wasNew) {
        this.sendNotificationEmail();
    }
});

Enquiry.schema.methods.sendNotificationEmail = function (callback) {
    if (typeof callback !== 'function') {
        callback = function () {};
    }
    var enquiry = this;
    keystone.list('User').model.find().where('isAdmin', true).exec(function (err, admins) {
        if (err) return callback(err);
        new Email('templates/emails/enquiry-notification.pug',{
            transport: 'mailgun',
        }).send({enquiry:enquiry
        }, {
            apiKey: 'MAILGUN API',
            domain: 'MAILGUN DOMAIN',
            to: '[email protected]',
            from: {
                name: 'Test',
                email: '[email protected]',
            },
            subject: 'Your first KeystoneJS email',
        }, function (err, result) {
            if (err) {
                console.error('🤕 Mailgun test failed with error:\n', err);
            } else {
                console.log('📬 Successfully sent Mailgun test with result:\n', result);
            }
        });
    });
};

Enquiry.defaultSort = '-createdAt';
Enquiry.defaultColumns = 'name, email, enquiryType, createdAt';
Enquiry.register();

All 10 comments

Ditto here:

TypeError: this.templateEngine.compile is not a function
    at Email.<anonymous> (/home/emmett/Projects/vsl-nutra/blog/node_modules/keystone/lib/email.js:347:35)
    at Email.<anonymous> (/home/emmett/Projects/vsl-nutra/blog/node_modules/keystone/lib/email.js:318:11)
    at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:445:3)

Im having this same issue, any luck?

No luck here. I just tore out the email function in the contact route.

Same here. Error in commandline and kills keystone:

================
GET /contact 200 115.724 ms
TypeError: this.templateEngine.compile is not a function
at Email. (/home/pelzla/Documents/acme/node_modules/keystone/lib/email.js:347:35)
at Email. (/home/pelzla/Documents/acme/node_modules/keystone/lib/email.js:318:11)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:438:3)
================> returns to prompt

Hey guys, it seems like keystone wants to have a valid mandrill api access, when using the precoded keystone contactform.
If no mandrill access is set up, keystone crashes by trying to send an email notification.

I "fixed" that issue by deleting the following lines (the commented lines are the lines I deleted) in the Enquiry.js :

Enquiry.schema.post('save', function () {
    if (this.wasNew) {
        // this.sendNotificationEmail();
    }
});

// Enquiry.schema.methods.sendNotificationEmail = function (callback) {
//  if (typeof callback !== 'function') {
//      callback = function () {};
//  }
//  var enquiry = this;
//  keystone.list('User').model.find().where('isAdmin', true).exec(function (err, admins) {
//      if (err) return callback(err);
//      new keystone.Email({
//          templateExt: 'hbs',
//          templateEngine: require('express-handlebars'),
//          templateName: 'enquiry-notification',
//      }).send({
//          to: admins,
//          from: {
//              name: 'Contact via marvin.works',
//              email: '[email protected]',
//          },
//          subject: 'New Enquiry for marvin.works',
//          enquiry: enquiry,
//      }, callback);
//  });
// };

Now i try to figure out an easy way for sending a notification-mail using the Emquiry.schema.post function :)

Works like a charm. However, I would like to use email feature.
Please suggest how this can be done. I think keystone should remove mandrill support and use an open source alternative.
Thanks again.

If I understand correctly, this is an issue with the the generator rather than keystone itself, so I'm going to close this here.

@anujmv i build something using the node package "nodemailer".This can send a mail via smtp using any mailbox. I hope I haven't forgotten anything, here.

Enquiry.js

var nodemailer = require('nodemailer');

Enquiry.schema.post('save', function () {
    if (this.wasNew) {
        var adminMailOptions = {
            from: this.name.first+" "+this.name.last+" <[email protected]>",
            to: "[email protected]",
            subject: "Enquiry: " + this.subject,
            html: "<h2>Message from "+this.name.first+" "+this.name.last+"(<a href='mailto:"+ this.email +"'>"+ this.email +"</a>) </h2><p>"+this.message.html+"</p>"
        };
        transporter.sendMail(adminMailOptions);
    }
});

var transporter = nodemailer.createTransport({
    host: "smtp.your.host",
    port: 465,
    secure: true,
    auth: {
    user: '[email protected]',
    pass: 'yourPassword'
    }
});

@marvinworks Thank you for your help.
However i found another solution too, using mailgun and keystone-email.

Please find the update Enquiry.js

var keystone = require('keystone');
var Types = keystone.Field.Types;
var Email = require('keystone-email');

/**
 * Enquiry Model
 * =============
 */

var Enquiry = new keystone.List('Enquiry', {
    nocreate: true,
    noedit: true,
});

Enquiry.add({
    name: { type: Types.Name, required: true },
    email: { type: Types.Email, required: true },
    phone: { type: String },
    enquiryType: { type: Types.Select, options: [
        { value: 'message', label: 'Just leaving a message' },
        { value: 'question', label: 'I\'ve got a question' },
        { value: 'other', label: 'Something else...' },
    ] },
    message: { type: Types.Markdown, required: true },
    createdAt: { type: Date, default: Date.now },
});

Enquiry.schema.pre('save', function (next) {
    this.wasNew = this.isNew;
    next();
});

Enquiry.schema.post('save', function () {
    if (this.wasNew) {
        this.sendNotificationEmail();
    }
});

Enquiry.schema.methods.sendNotificationEmail = function (callback) {
    if (typeof callback !== 'function') {
        callback = function () {};
    }
    var enquiry = this;
    keystone.list('User').model.find().where('isAdmin', true).exec(function (err, admins) {
        if (err) return callback(err);
        new Email('templates/emails/enquiry-notification.pug',{
            transport: 'mailgun',
        }).send({enquiry:enquiry
        }, {
            apiKey: 'MAILGUN API',
            domain: 'MAILGUN DOMAIN',
            to: '[email protected]',
            from: {
                name: 'Test',
                email: '[email protected]',
            },
            subject: 'Your first KeystoneJS email',
        }, function (err, result) {
            if (err) {
                console.error('🤕 Mailgun test failed with error:\n', err);
            } else {
                console.log('📬 Successfully sent Mailgun test with result:\n', result);
            }
        });
    });
};

Enquiry.defaultSort = '-createdAt';
Enquiry.defaultColumns = 'name, email, enquiryType, createdAt';
Enquiry.register();

@anujmv oh thats fine, maybe ill gonna check out mailgun! Seems like mandrill doesn't offer a free plan anymore, but mailgun does - thats cool! :)

Was this page helpful?
0 / 5 - 0 ratings