6

I am newbie in ExpressJs and module pattern in my project. Now, i am stuck that how to use created controller function in another controller. Please look at example :-

menu.ctrl.js
------------

module.exports.save=function(req,res,next){
    //here some logic
    //somethings like validate req.body,etc
    menu.save(function(err){
      if(err) return next(err);
      res.json({msg:'menu save'})
    }) 
}

user.ctrl.js
------------

var user=require('./user.model')
var menuCtrl=require('./menu.ctrl')
module.exports.save=function(req,res,next){
   //here some logic
   user.save(function(err){
      if(err) return next(err);
      //HERE I WANT TO USE `menuCtrl.save()` function
      res.json({msg:'success'});
   })
}
9
  • It's up to you how to solve that. Express is not an MVC framework. Commented Feb 28, 2017 at 17:03
  • try menuCtrl.save. Commented Feb 28, 2017 at 17:06
  • @YogeshPatel, throw an error Can't set headers after they are sent to the client Commented Feb 28, 2017 at 17:59
  • 1
    Decouple your Model actions from you controller logic. DB interactions should be done in models, controllers just format input and output for them and should not be called by anything else than the router. Commented Feb 28, 2017 at 18:15
  • 1
    @SharjeelAhmed, then how to handle this? Commented Mar 1, 2017 at 7:19

2 Answers 2

7

Decoupling your controller logic from your model logic will allow you reuse logic and make your application easier to maintain.

The idea is that controllers' purpose is to format input and output to and from you application, while models handle actual data manipulation. (This is a typical Rails-like MVC pattern for REST APIs)

To your example:

menuController.js

var menuModel = require('./menuModel');

module.exports.save = function(req, res, next) {
  menuModel.save(req.body, function(err) {
    if(err) return next(err);
    res.json({msg:'menu save'})
  });
};

menuModel.js

module.exports.save = function(body, callback) {
  // Save menu to the DB
  menu.save(body, callback);
};

userController.js

var userModel = require('./userModel');

module.exports.save = function(req, res, next) {
  userModel .save(function(err){
    if(err) return next(err);
    res.json({msg:'success'});
 });
}

userModel.js

var menuModel = require('./menuModel');

module.exports.save = function(body, callback) {
  // Save user to the DB
  user.save(body, function(err, res) {
    if (err) return callback(err);
    menuModel.save(body, callback);
  });
};

Rule of thumb, keep as less business logic as possible in controllers.

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

5 Comments

thanks @Frederic, but it wire to write multiple module.exports.save. Is there other way to achieve it?
Is your concern about naming? In my example I tried to reuse your convention, but ideally the exported method should have a more meaningful name.
no, i have to mean that here module.exports.save is written in userController.js and userModel.js.
it throw an error Can't set headers after they are sent to the ... when i call userController.js save method
Like I said, you should never call controller methods. That's the router's job. Put your logic in the model and call that instead.
1
//Here is a solution if you are using same route file
//

var getNotificationSetting = async function (user_id) {
  let params = {}

  params = await NotifcationSetting.findAll({
                                where: { ns_user_id : user_id },
                            });
  return params;
}

//now calling in action
router.get('/', async function(req, res, next) {
  let params = {}
  //for setting section
  params = await getNotificationSetting(req.session.user.user_id);

});

Comments

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.