0

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

validate_user is not on the list

its located

0

2 Answers 2

1

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: ... };

Sign up to request clarification or add additional context in comments.

Comments

1

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 ...

1 Comment

i see it now. so all i have to do is module.exports = { ..my functions.. }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.