Reputation: 496
Quoting only the important parts of the code.
This is my server.js
in the node backend server
//routes
const userapi = require('./api/routes/user');
//models
require('./api/models/userModel');
//use routes
userapi(app);
on my userapi
which is my routes I call my userController
(function () {
'use strict';
module.exports = function (app) {
var userCtrl = require('../controllers/userCtrl');
app.post('/api/validate_user', function(req, res, next){
userCtrl.validate_user(req, res);
});
}
})();
and this is my userController code. In the future, i will write a code that will handle all the transaction from my MongoDB.
'use strict';
var mongoose = require('mongoose'),
model = mongoose.model('users'),
brcpyt = require('bcrypt');
module.exports = function() {
return {
validate_user: function(req, res) {
console.log('here');
}
}
};
The problem is, everytime I make a http request from my frontend. I get an error that says userCtrl.validate_user
is not a function. My frontend can access the endpoints of '/api/validate_user'
and the var userCtrl = require('../controllers/userCtrl')
is a correct file path, but everytime that I type userCtrl
to my routes it does not give me function validate_user
Upvotes: 0
Views: 3228
Reputation: 1816
You really don't need to be wrapping your modules in IIFEs. That said, the issue you are seeing specifically is because your userCtrl module is exporting a function that, when called, returns an object which will then have a validate_user
member -- it's not exporting an object directly. Try checking the value of typeof userCtrl
- it'll be function
instead of an object
, which is what you're expecting here :)
Specifically, the following should work with no changes to userCtrl:
var userCtrl = require('../controllers/userCtrl')()
Notice the extra parenthesis at the end? That will invoke the exported function and give you back an object with a validate_user
method. This pattern is sometimes used when you'd like to pass some options to the module, like a factory pattern. For example,
const userCtrlFactory = require('../controllers/userCtrl')
const userCtrl = userCtrlFactory({ option: value })
This, however, is not the best way to do so, you would be using classes for that.
I recommend you drop the IIFEs from your code ((function () {})()
) and just have a top-level module.exports
(like you did with the userCtrl) that exports either an object or a class, depending on what you need from it. For userCtrl, just export an object directly as you're not passing options or have a need for "instantiating" a controller more than once:
'use strict';
module.exports = {
validate_user: ...
};
Upvotes: 1
Reputation: 70584
require gives you the value assigned to module.exports, so your code is like:
var userCtrl = function() {
return {
validate_user: function(req, res) {
console.log('here');
}
}
};
userCtrl.validate_user(...);
Do you see the bug now? userCtrl is a function, and therefore doesn't have a validate_user property ...
Upvotes: 1