Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better place to setup an initialisation in SailsJS

I'm new to Sails and don't know exactly where to put the initialisation of an object to be unique in all the app. After reading the docs I assumed that I can have it in the global sails object, but not sure if is the better place.

I'm using the new Appcelerator ArrowDB to store my users and objects. Docs talk about declare the appropriate vars and use it, with the APP_KEY.

var ArrowDB = require('arrowdb'),
    arrowDBApp = new ArrowDB('<App Key>');
function login(req, res) {
    var data = {
        login: req.body.username,
        password: req.body.password,
        // the req and res parameters are optional
        req: req,
        res: res
    };
    arrowDBApp.usersLogin(data, function(err, result) {
        if (err) {
            console.error("Login error:" + (err.message || result.reason));
        } else {
            console.log("Login successful!");
            console.log("UserInfo: " + JSON.stringify(result.body.response.users[0]));
        }
    });
}

But I will need to use constantly that arrowDBApp var to create, update, delete objects in the database, so I think the best way is to initialize it in the starting script app.js and share across the app.

I tried it, but I was not able to store it in the sails var, it seems that this var is not available (or lose its config) until sails.lift() is executed.

This code (app.js file) shows nothing in the console:

// Ensure we're in the project directory, so relative paths work as expected
// no matter where we actually lift from.
process.chdir(__dirname);

// Ensure a "sails" can be located:
(function() {
  var sails;
  try {
    sails = require('sails');
  } catch (e) {
    console.error('To run an app using `node app.js`, you usually need to have a version of `sails` installed in the same directory as your app.');
    console.error('To do that, run `npm install sails`');
    console.error('');
    console.error('Alternatively, if you have sails installed globally (i.e. you did `npm install -g sails`), you can use `sails lift`.');
    console.error('When you run `sails lift`, your app will still use a local `./node_modules/sails` dependency if it exists,');
    console.error('but if it doesn\'t, the app will run with the global sails instead!');
    return;
  }

  // Try to get `rc` dependency
  var rc;
  try {
    rc = require('rc');
  } catch (e0) {
    try {
      rc = require('sails/node_modules/rc');
    } catch (e1) {
      console.error('Could not find dependency: `rc`.');
      console.error('Your `.sailsrc` file(s) will be ignored.');
      console.error('To resolve this, run:');
      console.error('npm install rc --save');
      rc = function () { return {}; };
    }
  }

  // My own code
  var APP_KEY = 'mykey';
  var ArrowDB = require('arrowdb');
  sails.arrowDBApp = new ArrowDB(APP_KEY);
  console.log("Hi" + JSON.stringify(sails));

  // Start server
  sails.lift(rc('sails'));
  console.log("Finish");
})();

No "HI" and no "Finish" are printed. If I try to use sails.arrowDBApp in another controller, it is undefined.

Tips are welcome.

like image 527
Eagle Avatar asked Jul 06 '15 13:07

Eagle


2 Answers

It's not advisable to modify app.js unless you really need to.

The usual space to save all configuration information (e.g. the APP_KEY) is in the config directory in your project root.

One-time initializations (e.g. ArrowDB initialization) can be added to config/bootstrap.js.

Update

In config/arrowdb.js (you need to create this file yourself):

module.exports.arrowdb = {
   APP_KEY: 'yourappkey',
   ArrowDBApp: null
};

In config/bootstrap.js:

var ArrowDB = require('arrowdb');

module.exports.bootstrap = function(next){
    sails.config.arrowdb['ArrowDBApp'] = new ArrowDB(sails.config.arrowdb['APP_KEY']);
    next(); // Don't forget to add this
};

In your controller:

'task': function(req, res, next) {
    sails.config.arrowdb['ArrowDBApp'].usersLogin(...);
    // and so on.
    // You could also add something like 
    // var ADB = sails.config.arrowdb['ArrowDBApp'];
    // at the top in case you need to use it on and on.
}
like image 181
galactocalypse Avatar answered Sep 29 '22 03:09

galactocalypse


  1. Use config/bootstrap.js to initialize something before Sails lifted. Sometimes if we want to put something in global variable, this approach is good to use, like define/ override native Promise with Bluebird Promise.
  2. Use api/services to put some method or other things that you will use regularly in your code (controllers, models, etc.), like Mail Service, that handle sending email within your application.
  3. Use config at config folder to predefined something at sails.config[something]. It can be an object, function, or whatever in order to become configurable, like put Twitter API Key to use Twitter REST API.

To achieve what you wanted, I'll try to use service and bootstrap.js. Try this example.

  1. Create service file at api/services/ArrowDBService.js
  2. Put with this code:

    var ArrowDB    = require('arrowdb'),
        arrowDBApp = new ArrowDB('<App Key>');
    
    module.exports = {
        arrowDBApp : arrowDBApp,
        login      : function (req, res) {
            var data = {
                login: req.body.username,
                password: req.body.password,
                // the req and res parameters are optional
                req: req,
                res: res
            };
            arrowDBApp.usersLogin(data, function(err, result) {
                if (err) {
                    console.error("Login error:" + (err.message || result.reason));
                } else {
                    console.log("Login successful!");
                    console.log("UserInfo: " + JSON.stringify(result.body.response.users[0]));
                }
            });
        }
    };
    

Now you can use it by sails.services.arrowdbservice.login(req,res) or simply ArrowDBService.login(req,res) (notice about case sensitive thing). Since I don't know about ArrowDB, so you may explore by yourself about login method that your example provide.

like image 42
Andi N. Dirgantara Avatar answered Sep 29 '22 01:09

Andi N. Dirgantara