6

I'm trying to assign a constructor in a self-executing function in NodeJS. I'm pretty sure it's not working because my parameter is a variable pointing to module.exports, but I'm curious if there's a way to make it work while staying as close to the self-executing format as possible.

Here's how the code is being called...

var TemplateEngine = require('./templateEngine');
templateEngine = new TemplateEngine({engine: 'swig'}); // "object is not a function"

Here's an example of code that works fine...

var assert = require('assert');
var swig = require('swig');

// Constructor
var TemplateEngine = function(args) {
    assert.ok(args.engine, 'engine is required');
    var templateEngine = {};

    templateEngine.engine = args.engine;

    templateEngine.Render = function(templateString, model) {
        var result = swig.render(templateString, model);
        return result;
    };

    return templateEngine;
};

module.exports = TemplateEngine;

and here's an example of the code style I'd like to use, but which produces a "TypeError: Object is not a function" error because I'm not actually assigning to module.exports, just a variable that copied whatever it was pointing to.

(function(templateEngine) {
    var assert = require('assert');
    var swig = require('swig');

    templateEngine = function(args) {
        assert.ok(args.engine, 'engine is required');
        var templateEngine = {};

        templateEngine.engine = args.engine;

        templateEngine.Render = function (templateString, model) {
            var result = swig.render(templateString, model);
            return result;
        };

        return templateEngine;
    };
})(module.exports);

Is there a way for me to use the above self-executing format and have my module export a Constructor?

Tim Hardy
  • 1,654
  • 1
  • 17
  • 36
  • module.exports needs to be assigned in the 2nd code, maybe something like module.exports=new templateEngine(); ? – dandavis Feb 13 '15 at 19:46
  • 1
    you have to many templateEngine variables... – lujcon Feb 13 '15 at 19:51
  • This style is not needed. You can use it to hide private variables... but on client side. With modules in nodejs everything not assigned to module.exports is private so this pattern is useless. – lujcon Feb 13 '15 at 19:57
  • I agree it doesn't provide any functional benefit, but it's pretty nice for organization. You can name module.exports whatever you want in the parm, like "controller" then whatever you assign to controller.someProp = or controller.someFunction = is what you're exporting. I suppose you can do the same thing with an object, so it's more of a preference. I'm realizing all of that is lost when exporting a constructor, so it might be extra useless in this case. – Tim Hardy Feb 13 '15 at 20:12

1 Answers1

9

In your second example, you are simply overwriting the templateEngine parameter, and that's not going to have any effect.

To get the same result as your first example, simply:

Pass module into your IIFE:

(function(module) {

})(module);

Assign a property to that:

(function(module) {
    var assert = require('assert');
    var swig = require('swig');

    module.exports = function (args) {
       ...
    };

})(module);
JLRishe
  • 99,490
  • 19
  • 131
  • 169
  • Wow. Don't know why I didn't think of that. I'll try it when I get home, but I'm thinking this will work great. – Tim Hardy Feb 13 '15 at 19:58
  • Thank you for your answer! Whilst it wasn't in direct relation to what I was doing, this really was helpful to create my solution! – jaseeey Sep 18 '15 at 07:57