43

I'm converting an app of mine from Express to sails.js - is there a way I can do something like this in Sails?

From my app.js file in Express:

var globals = {
    name: 'projectName',
    author: 'authorName'
};

app.get('/', function (req, res) {
    globals.page_title = 'Home';
    res.render('index', globals);
});

This let me access those variables on every view without having to hardcode them into the template. Not sure how/where to do it in Sails though.

Travis Webb
  • 14,688
  • 7
  • 55
  • 109
user2688473
  • 633
  • 1
  • 6
  • 8
  • 1
    Worth noting that Sails provides environments that are suitable for this, under `/config/env`. Nice thing here is that things can be different between prod, dev, and testing if necessary. –  Dec 10 '14 at 20:45

2 Answers2

93

You can create your own config file in config/ folder. For example config/myconf.js with your config variables:

module.exports.myconf = {
    name: 'projectName',
    author: 'authorName',

    anyobject: {
      bar: "foo"
    }
};

and then access these variables from any view via global sails variable.

In a view:

<!-- views/foo/bar.ejs -->
<%= sails.config.myconf.name %>
<%= sails.config.myconf.author %>

In a service

// api/services/FooService.js
module.exports = {

  /**
   * Some function that does stuff.
   *
   * @param  {[type]}   options [description]
   * @param  {Function} cb      [description]
   */
  lookupDumbledore: function(options, cb) {

    // `sails` object is available here:
    var conf = sails.config;
    cb(null, conf.whatever);
  }
};

// `sails` is not available out here
// (it doesn't exist yet)
console.log(sails);  // ==> undefined

In a model:

// api/models/Foo.js
module.exports = {
  attributes: {
    // ...
  },

  someModelMethod: function (options, cb) {

    // `sails` object is available here:
    var conf = sails.config;
    cb(null, conf.whatever);
  }
};

// `sails is not available out here
// (doesn't exist yet)

In a controller:

Note: This works the same way in policies.

// api/controllers/FooController.js
module.exports = {
  index: function (req, res) {

    // `sails` is available in here

    return res.json({
      name: sails.config.myconf.name
    });
  }
};

// `sails is not available out here
// (doesn't exist yet)
mikermcneil
  • 11,141
  • 5
  • 43
  • 70
ataman
  • 2,644
  • 17
  • 22
  • To simplify the access in the view, I went with something like `module.exports.name = 'projectName';` and accessed it with `sails.config.name`. – user2688473 Aug 16 '13 at 17:27
  • For my page title, I just used `res.locals.page_title = 'Page Title'` before the `res.render()`/`res.view()` is called. – user2688473 Aug 17 '13 at 07:12
  • 2
    Of couse, to simplify access, you can write configs as `module.exports.name = 'projectName';`. All that you export from config files become part of global `sails.config` object. But I still recommend to wrap custom config variables in namespaces to avoid accidental replacing of important sails` config options. – ataman Aug 17 '13 at 08:49
  • To add to @atarman's excellent example, it's worth pointing out you can access the global `sails.config` from any controller, model, policy, or service as well. – mikermcneil Aug 17 '13 at 19:11
  • 2
    @mikermcneil Is it possible to use configuration variables (like those set in locals) inside another configuration file? – Jason Kulatunga Feb 21 '14 at 06:40
  • yep! The files themselves don't actually matter-- just what you export from them. So you can make a file `config/foo.js` and inside of it: `module.exports.bar= { baz: 23852835 };` Then you can access `sails.config.bar.baz` the same way as the rest of the built-in sails config. – mikermcneil Feb 21 '14 at 19:13
  • 1
    How would I be able to set up a service using `sails.config` outside of the module.exports functions it exposes. For example, a NodeMailer service that first sets up the transport and in the module exports exposes only a send function that uses that transport object. When using `sails lift` it works fine having the `sails.config` outside of module exports, but in `sails www` an error, `sails is undefined`, pops up. – jreptak Aug 25 '14 at 02:16
  • @mikermcneil What about other requests? If I store that info as you mention in `config/foo.js` When another incoming request override this data the first one will lose the info it store first? Or it will be one instance of that module per each request and store data separately? – alexventuraio Feb 23 '16 at 16:34
  • @Lexynux your app's configuration files are loaded from disk only once when Sails lifts, so you'll need to kill and re-lift the server to pick up any changes you make to the configuration file itself (and/or have a look at sails-hook-autoreload). As for the programmatic configuration (`sails.config`), it _is mutable_. So if you change `sails.config` in your code, those changes will stick around until Sails is re-lifted. As a rule of thumb, it's best to avoid changing `sails.config` in userland code. (However it is totally kosher to do so in the `configure()` function of a custom hook) – mikermcneil Mar 03 '16 at 03:31
  • @mikermcneil What I meant is to have a global variable where to store user logged in data. I mean, like Devise in Rails does. Once the user has logged in expose its data to be accessible from al over the app (controllers, models, views, etc.). I want to have something similar in SailsJS but not using cookies because I'm using JWT in my API app. – alexventuraio Mar 03 '16 at 17:37
  • @AlexVentura to do that in Sails, you'll want to use `req.session`. To make the session support JWT instead of cookies, you'd need to override the session hook. But before doing that, I'd suggest taking a look at the JWT hooks built by the members of the community: https://www.npmjs.com/search?q=sails+jwt – mikermcneil Nov 15 '16 at 21:07
  • @mikermcneil Ok, I will take a look at those hooks to see what I can do. Thanks in advance! – alexventuraio Nov 17 '16 at 17:05
  • @mikermcneil `config/foo.js and inside of it: module.exports.bar= { baz: 23852835 }; sails.config.bar.baz` is thrown sails not found error – Jabaa Jul 20 '17 at 09:25
  • this approach is great! just it might cause a bit of troubles when testing the function in isolation. Not sure how to go about, at the moment I am passing in the config as a param. Would be nice to know if there was a way to mock/stub the globals – mikey Aug 13 '19 at 00:44
0

I just made a service which delivers a value:

maxLimbs: function(){
        var maxLimbs = 15;
        return maxLimbs;
    }
Matt Payne
  • 198
  • 4
  • 15