reference sails config outside module.exports - sails.js

How can I use sails.config outside the module.exports? I'm trying to pass sails.config variables to another object, something like below;
var foo = new Foo(sails.config.myconf.myVar);
module.exports {
bar : function(){
// Use foo here
foo.blah();
}
};
(Same question also asked in a comment in this Create config variables in sails.js? See #jreptak comment)

Each files of Sails config is a module then if you want to use it, you just have to import it.
Here is an example to import Sails connections of sails.config.connections module.
Be careful about the path of the module in the require, it must be relative.
var connections = require('../../config/connections');

This was not possible in Sails v0.9. However, this is now possible in Sails v0.10 onwards.
Here's the specific issue on github: https://github.com/balderdashy/sails/issues/1672
So now you can do something like this:
//MyService.js
var client = new Client(sails.config.client);
module.exports = {
myMethod: function(callback){
client.doSomething();
}
}
If you're stuck with Sails v0.9, I would recommend that you follow the workaround specified in the github issue:
//MyService.js
var client;
module.exports = function(){
client = client || new Client(sails.config.client);
return {
myMethod: function(){
client.doSomething();
}
}
}
Which can be used like so:
//SomeController.js
module.exports = {
list: function(req,res){
MyService().myMethod();
}
}

You can't do this, if you want to access sails.config params you have to create a custom hook http://sailsjs.org/documentation/concepts/extending-sails/hooks and do your 'magic' in it

Related

Is it possible to create a file with all my functions and read from from it in my specs?

I have some specs that are using the same functions, I would like to make one single file only for functions and read from this file while executing my scripts, would be that possible? if so.. how to do that?
During google searchers I found the "exports" to add in config file but didn't work (also I don't know how to call it from the config)
For example, I would like to add 2 functions in my config file (or separated file only for functions) and during any point of my execution, call it from the spec file:
function loginAdminUser(userElement, passWordElement, userName, password){
var loginButton = element(by.id('logIn'));
browser.get('https://( ͡° ͜ʖ ͡°).com/');
userElement.sendKeys(userName);
passWordElement.sendKeys(password);
loginButton.click();
}
function accessHistoryViewDetail(){
menuForViews.then(function(selectview) {
selectview[3].click();
browser.sleep(500);
});
}
1 - How can I do that? (using "Suites" would be an option?)
2 - How to call them in my specs?
Thank you and have a good day!
As far as I know you cannot add utility functions that you want to use in your tests in the config file. The options in the config file are generally for setting up the testing environment.
You can however put your functions in a separate file and import that to use the functions. Below is an example of how to do that using js and Node's module exports, you can do something similar with ts using classes.
// utils.js
function loginAdminUser(userElement, passWordElement, userName, password){
var loginButton = element(by.id('logIn'));
browser.get('https://( ͡° ͜ʖ ͡°).com/'); // nice Lenny face :)
userElement.sendKeys(userName);
passWordElement.sendKeys(password);
loginButton.click();
}
function accessHistoryViewDetail() {
menuForViews.then(function(selectview) {
selectview[3].click();
browser.sleep(500);
});
}
module.exports = {
loginAdminUserloginAdminUser: loginAdminUser,
accessHistoryViewDetail: accessHistoryViewDetail
}
Then in your spec file
import * as utils from './utils.js';
...
it('should ...', () => {
...
utils.accessHistoryViewDetail();
...
});
});
I hope that helps.

How do I access environment variables in config SailsJS

I'm trying to access my environment variables inside a config file. Can I use this variable inside a config?
For example
// config/env/development.js
module.exports = {
appUrl: 'http://MY_DEV_PLACE/',
}
//config/passport.js
var appUrl = appUrl || sails.config.appUrl || 'localhost:1337'; //<-- sails is not defined
I also tried in local.js:
// config/local.js
module.exports = {
gAPI: { secret: 'aaa'}
}
//config/passport.js
var appUrl = gAPI || sails.config.gAPI || 'some pass'; //<-- sails is not defined
EDIT:
For appURL I'm using env like: APP_URL=http://example.com/api sails lift
For password I'm using:
var locals;
try {
locals = require('./local');
} catch (e) {
// not local so just ignore
}
module.exports.passport = {
'GoogleAPI.Password': locals ? locals.gAPI.secret : ’some key'
};
You can use the local.js file for environment variables. This file is discussed in-depth here. This is pretty much the go to for storing environment variables in sails.
Important caveats: make sure this file is included in your .gitignore file lest you risk exposing important information to the world, this file will need to be configured for each environment (e.g. local, staging, production), you can access your environment variables via sails.config.variable_name, this file will take priority over the development.js and production.js file in the /env/ sub-directory.
I accessed the sails object from the routes.js like this:
module.exports.routes = {
'/': (req, res) => {
res.redirect(sails.config.frontendUrl)
}
}
In config/global.js add the following line....
sails: true,
This makes sails instance global.

Meteor onRendered function and access to Collections

When user refresh a certain page, I want to set some initial values from the mongoDB database.
I tried using the onRendered method, which in the documentation states will run when the template that it is run on is inserted into the DOM. However, the database is not available at that instance?
When I try to access the database from the function:
Template.scienceMC.onRendered(function() {
var currentRad = radiationCollection.find().fetch()[0].rad;
}
I get the following error messages:
Exception from Tracker afterFlush function:
TypeError: Cannot read property 'rad' of undefined
However, when I run the line radiationCollection.find().fetch()[0].rad; in the console I can access the value?
How can I make sure that the copy of the mongoDB is available?
The best way for me was to use the waitOn function in the router. Thanks to #David Weldon for the tip.
Router.route('/templateName', {
waitOn: function () {
return Meteor.subscribe('collectionName');
},
action: function () {
// render all templates and regions for this route
this.render();
}
});
You need to setup a proper publication (it seems you did) and subscribe in the route parameters. If you want to make sure that you effectively have your data in the onRendered function, you need to add an extra step.
Here is an example of how to make it in your route definition:
this.templateController = RouteController.extend({
template: "YourTemplate",
action: function() {
if(this.isReady()) { this.render(); } else { this.render("yourTemplate"); this.render("loading");}
/*ACTION_FUNCTION*/
},
isReady: function() {
var subs = [
Meteor.subscribe("yoursubscription1"),
Meteor.subscribe("yoursubscription2")
];
var ready = true;
_.each(subs, function(sub) {
if(!sub.ready())
ready = false;
});
return ready;
},
data: function() {
return {
params: this.params || {}, //if you have params
yourData: radiationCollection.find()
};
}
});
In this example you get,in the onRendered function, your data both using this.data.yourData or radiationCollection.find()
EDIT: as #David Weldon stated in comment, you could also use an easier alternative: waitOn
I can't see your collection, so I can't guarantee that rad is a key in your collection, that said I believe your problem is that you collection isn't available yet. As #David Weldon says, you need to guard or wait on your subscription to be available (remember it has to load).
What I do in ironrouter is this:
data:function(){
var currentRad = radiationCollection.find().fetch()[0].rad;
if (typeof currentRad != 'undefined') {
// if typeof currentRad is not undefined
return currentRad;
}
}

Using port.emit and port.on in a firefox extension

Can someone please explain the context in which port.on and port.emit are used in a firefox extension?
From the official documentation I imagine that this should work:
//main.js
var someData = "Message received";
self.port.emit("myMessage", someData);
self.port.on("myMessage", alert(someData));
but I get
Error: self is not defined.
After attaching this to a defined object like this:
var self = require("sdk/self");
self.port.emit("myMessage", someData);
I get
Error: port is not defined.
If you use the page-mod module to inject a content script into a web page, you then use self.port in the content script to communicate back with main.js. For example:
main.js:
var data = require('sdk/self').data;
require('sdk/page-mod').PageMod({
include: ["*"],
contentScriptFile: [data.url('cs.js')],
attachTo: ["existing", "top"],
onAttach: function(worker) {
worker.port.emit('attached', true);
}
});
cs.js:
self.port.on('attached', function() {
console.log('attached...');
});
For the related documentation, start here:
https://developer.mozilla.org/en-US/Add-ons/SDK/Guides/Content_Scripts

Custom PhoneGap Plugin (iOS) Function Issue

I'm using this tutorial to create a custom PhoneGap plugin:
http://wiki.phonegap.com/w/page/36753496/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20iOS
I have had success using the author's example, but I have a few questions that I have not been able to find out the answers to.
When the JavaScript function is created, the code is:
var MyPlugin = {
nativeFunction: function(types, success, fail) {
return PhoneGap.exec(success, fail, "PluginClass", "print", types);
}
};
Is there a way to set this up without var MyPlugin = {...}; and nativeFunction? In other words, can we define a function of our plugin like myfunc = function()...
Secondly, assuming there is a way to do the above, could this code:
MyPlugin.nativeFunction(
["HelloWorld"] ,
function(result) {
alert("Success : \r\n"+result);
},
function(error) {
alert("Error : \r\n"+error);
}
);
(which is the test code to test the plugin) also be written in a more standardized way? I.e., just a call to Javascript function without the nativeFunction part?
I would very much appreciate any input, thank you!
the phonegap documentation for plugins sucks. Honestly I had a bunch of issues when trying to create my own. A few tips :
the reason for doing
var MyPlugin = {};
is because this allows us to us scope things specific to that js object.
example:
MyPlugin.myFunction();
My favorite method to create plugins, similar to your question, is to prototype them
var MyPlugin = {}; // our object
MyPlugin.prototype.myFunction = function(success,fail,types){
}
The key to making a plugin fire is this -
PhoneGap.exec(success,fail,"MyPlugin","myFunction",types);
But something that they leave out is, what if we want to have options to our plugin? What if we want to do more than pass a string, then the example doesn't work. The fix is easy but not talked about at all.
var MyPlugin = {};
MyPlugin.prototype.myFunction = function(success,fail,options){
var defaults = {
foo: '', // these are options
bar: '',
};
// this parses our "options"
for(var key in defaults) {
if(typeof options[key] !== "undefined") defaults[key] = options[key];
}
return PhoneGap.exec(success,fail,"MyPlugin","myFunction",[defaults]);
}
when we call this with out javascript -
var foo = MyPlugin.myFunction(success,fail,{
foo:'hello',
bar:'world'
});
You'll notice that most of the phonegap API uses this syntax, which I found strange that their documentation didn't really talk about how to do this.
I have a post about a plugin I create you can check it out for reference.
Blog - http://www.drewdahlman.com/meusLabs/?p=138
Git - https://github.com/DrewDahlman/ImageFilter