3

In controller, it's easy. Accessing a session variables is straightforward:

req.session.x = 1

However, how do I access that outside controller? Like in service?

module.exports.test = function() {
    // No req.session here?
};
nhaa123
  • 9,570
  • 11
  • 42
  • 63

2 Answers2

3

You can create a main controller that will register req and res in all of your services for each route controller called.

Here is the code of my main controller:

module.exports = function MainController() {

  var _this = this;

  function _execRouteMethod(req, res) {
    // Add here your services or whatever with a registration
    // of req and/or res variables
    ActiveUserService.registerRequest(req);
  }

  // Abstract function for calling registers before the original method
  function _abstractRouteMethod(functionName) {
    var funcSuper = _this[functionName];
    _this[functionName] = function(req, res) {
      _execRouteMethod(req, res);
      funcSuper(req, res);
    }
  }

  // Loop for all method that have req and res arguments
  for(var functionName in this) {
    if(typeof this[functionName] == 'function') {
      var args = /function[^\(]*\(([^\)]*)\)/.exec(
        this[functionName].toString()
      );
      if(args && args.length > 1) {

        args = args[1].split(',').map(function(arg) {
          return arg.trim()
        });

        if(args.length == 2 && args[0] == 'req' && args[1] == 'res') {
          _abstractRouteMethod(functionName);
        }
      }
    }
  }

};

Now you can call it in any of your controllers :

var MainController = require('./MainController');
MainController.call(MyController);

Your services can use the req and res registered. For exemple, I use it in my ActiveUserService like this:

var _request = null;

var ActiveUserService = {

  registerRequest: function(req) {
    _request = req;
  },

  isConnected: function () {
    return _request && _request.session.user ? true : false;
  },

  // ...

};
Xavier Boubert
  • 139
  • 1
  • 7
2

The session object in Sails isn't provided as a global; it's a property of the Request object. For server-side code that doesn't included the request as part of the scope (like services and models), you'll need to pass the request or the session along as an argument to your function:

modules.exports.test = function(session) {
   ...
}

and call it from a controller with MyService.test(req.session).

Note that for views, req is passed down by default with the view locals, so you can do (in EJS) things like:

<%= req.session.myVar %>
sgress454
  • 24,870
  • 4
  • 74
  • 92
  • Thanks for the answer, but I'm having the same problem and still am a bit lost about how I can do the same with models - and more specifically with model lifecycle callbacks like beforeCreate: fn(values, cb). Any help is greatly appreciated! :) – veturi Aug 17 '14 at 20:00
  • You can't access the session directly in lifecycle callbacks, unless you pass it in as an attribute value to `create` or `update`, which is a terrible idea. Anything you can do in a lifecycle callback you can do with a custom controller action or service as well; that's where your session handling logic should go. See [this answer](http://stackoverflow.com/questions/22853179/sailjs-use-session-param-in-model/22855255#22855255) for a more complete explanation of why you can only access the session in the context of a request. – sgress454 Aug 17 '14 at 21:06