2

Does anybody know proper way to pass context to sails controllers action? Here is my case why I want to do it:

--- AbstractPageController.js ---

module.exports = {
    _getPageData: function(req, res) {
        return {
            data: {
                title: this._getTitle(req, res), // if do nothing "this" is global object
                menu: this._getMenu(req, res)
            }
        };
    },

    _getTitle: function(req, res) { return 'Cool Page'; },

    _getMenu: function(req, res) { return [{ href: '/logout' }]; }
};

--- ConcretePageController.js ---

var _ = require('lodash');
    _super = require('./AbstractPageController.js');

module.exports = _.merge({}, _super, {

    'main': function(req, res) {
        res.view('pageTemplate', this._getPageData(req, res));
    },

    _getTitle: function(req, res) {
        return 'Absolutely - ' + _super._getTitle(req, res);
    },

    _getMenu: function(req, res) {
        return [{ href: '/main/'}].concat(_super._getMenu(req, res));
    }
});

That's why I need context.

For this particular case I found this solution:

--- routes.js ---

var concreteController = require('../api/controllers/ConcretePageController.js');

module.exports.routes = {
    '/concrete_page': function(req, res) { concreteController.main(req, res); }
}

But it seems a little bit ugly and sails hooks (for example policies) stop works.

I was thinking about the other way. The main point of this, is to move all logic to services and to use a simple inheritance. But this seems strange for me too

Any ideas about a better way to reach the cases I have wrote?

P.S. All code I have wrote above is just an example.

jetli13
  • 593
  • 5
  • 9
  • What is your sails' version? Didn't you use the Sails generator? The current default config/routes.js is just marvel. – Creasixtine Oct 24 '14 at 18:47
  • just general answer - bind]: `action: handler.bind(context);` – zb' Oct 25 '14 at 08:22
  • i.e. your sample could look like: `'/concrete_page': concreteController.main.bind(concreteController)` – zb' Oct 25 '14 at 08:24

2 Answers2

1

I think you whant to pre-set some data to send to view template, right?

is yes you can use one Before hook ( like midleware ) or sails police

I use the sails hook for preload sails features from npm modules in we-plugin https://github.com/wejs/we-plugin

Check this hook for how load user locale in all requests after controllers : Link: https://github.com/wejs/we-example/blob/master/api/hooks/we-locale/index.js#L15

Alberto Souza
  • 681
  • 5
  • 10
  • Thank you for answer! Exactly not, I just want to use template method pattern http://en.wikipedia.org/wiki/Template_method_pattern – jetli13 Oct 16 '14 at 18:12
  • I've never used this type of structure in javascript (already used in PHP) ... but I think you could try with prototypes, creating a prototype Link: http://www.w3schools.com/js/js_object_prototypes.asp or use one callback in AbstractPageController.js ... – Alberto Souza Oct 16 '14 at 19:59
  • Unfortunately using prototypes will not solve problem because I steel need context to use "this" keyword. Second way with callback will work, but such solution seems not like proper way. Anyway thanks for help – jetli13 Oct 16 '14 at 21:06
  • I did PR https://github.com/balderdashy/sails/pull/2318 mb it will interesting to you – jetli13 Nov 18 '14 at 04:55
1

You should just reference the controller directly

sails.controllers.yourControllerName.getTitle()

https://stackoverflow.com/a/20994036/1821723

Community
  • 1
  • 1
Meeker
  • 5,979
  • 2
  • 20
  • 38
  • I will not reach the goal. Imagine what result I will get if I try to use your solution sails.controllers.AbstractPageController._getPageData() in 'main' action of ConcretePageController – jetli13 Oct 31 '14 at 09:08