Ivan Bertola
Ivan Bertola

Reputation: 261

Export a function with Node JS

I need help with function export in Node.Js

Here is my module.js

var knex = require('knex')({
    client : 'mysql',
    connection : {
        host : 'localhost',
        user : 'root',
        password : '123',
        database : 'dbNode'
    }
}),bookshelf = require('bookshelf')(knex);

var user = bookshelf.Model.extend({
   tableName : 'tblUsers',
   idAttribute : 'email'
});

var note = bookshelf.Model.extend({
   tableName : 'tblNotes',
   idAttribute : 'noteId'
});


module.exports = {
   User : user,
   Note : note,

};

module.exports = function(owner) {
  return knex('note').where('public',1).orWhere({ownerName : owner}).select('noteId');
}

I have to export both the function and the bookshelf models (User and Note) but when I try to use the Model.User it returns me the error: Model.User is not a function

Upvotes: 9

Views: 17682

Answers (3)

fregante
fregante

Reputation: 31688

Let's look at your code:

module.exports = {
    ...
};

module.exports = function(owner) {
    ...
}

You're assigning two different things to the same property. The second assignment overrides the first one.


To do what you're asking, you need to export the function first and then add the properties separately:

module.exports = function(owner) {
    ...
}

module.exports.User = user;
module.exports.Note = note;

This is standard in node.

Better yet, don’t assign the function directly to module.exports but add it as a property to it:

module.exports.myFunction = function(owner) {
    ...
}

module.exports.User = user;
module.exports.Note = note;

This way you have real separate exports instead of an exported function that strangely also has User and Note properties.

Upvotes: 10

Valkyrie
Valkyrie

Reputation: 861

Instead of defining note and user with var, use exports.note and exports.user

 exports.user = bookshelf.Model.extend({
    tableName : 'tblUsers',
    idAttribute : 'email'
 });

 exports.note = bookshelf.Model.extend({
    tableName : 'tblNotes',
    idAttribute : 'noteId'
 });

Then you'll more likely than not have to set your function export to a named function. (or make it a class?)

 exports.MyClass = function(owner) {
   return knex('note').where('public',1).orWhere({ownerName : owner}).select('noteId');
 }

If you're worried about ease of imports, you can assign MyClass to a variable, instead of the whole package

 var MyClass=require('module').MyClass;

Upvotes: 3

libik
libik

Reputation: 23029

What you put into "module.exports" is exported.

If you use it several time, the last one overides everything else. In your case, you put a function into it, which overriders object with User and Note which was there before.

In your case, this can be the solution

module.exports = {
   User : user,
   Note : note,
   returnNoteByOwner(owner) {
      knex('note').where('public',1).orWhere({ownerName : owner}).select('noteId');
   }
};

Then you can access it as following

var module = require('module');
console.log(module.User);
console.log(module.Note);
console.log(module.returnNoteByOwner('hisName'));

Upvotes: 0

Related Questions