How to add configuration settings to locals on Sails.js - javascript

I'm building a webapp using Sails.js and I'm wondering how to have different configurations on development and production modes. I thought that I just had to put a configuration key in config/local.js but it doesn't work. Here's an example of what I'm trying to do:
config: {
linkedIn_key: 'abcde',
linkedIn_secret: '13mcas',
linkedIn_url: 'http://localhost:1337/user/login'
}
I tried to access config in the UserController.js but I wasn't able to get the value. What is the right way to do it?
Best regards,
João

It should appear in sails.config. You can also try to create a new file: linkedin.js under the config folder and place your configurations there:
var linkedIn = {
key: 'abcde',
secret: '13mcas',
url: 'http://localhost:1337/user/login'
};
module.exports.linkedin = linkedIn;
and access it in your controller via
sails.config.linkedin

Related

Angular 4 create assets / files per environment?

We use environment variables within our angular app to read settings etc but is there a way to generate assets/files on build?
Basically we'd like to create an 'auth/settings.js' file in the assets folder containing client id's and apiUrl's unique to each environment. These will be used in the index.html (so outside of the angular app bootstrap )
e.g. the values in the environment.ts exported into a js / json file output to the assets folder so they can be read in index.html
export const environment = {
production: false,
title: 'default',
clientId: 'xxxx-xxxx-xxxx-xxxx-xxxx',
clientUrl: 'https://localhost:4200/app',
apiUrl: 'https://localhost/api'
};
I have read that you can use mulitapps:
https://github.com/angular/angular-cli/wiki/stories-multiple-apps
This may work but looks like a lot of copy and pasting and we'll have quite a few versions of the build - I'm not sure if you can declare the common settings once and just extend the extra app settings (inheritance)?
Thanks
What we are doing in our case is actually having an config.json and config.[env-name].json files in app/config folder that configured in project assets. The config.json file is getting fetched before angular bootstrap using browser Fetch API
On our build server we are just replacing the content of config.json withconfig.staging.json or config.prod.json based on environment build. Also we have AppSettings class that gets created on bootstrap. Here is how it is looks like:
fetch(configUrl, { method: 'get' })
.then((response) => {
response.json()
.then((data: any) => {
if (environment.production) {
enableProdMode();
};
platformBrowserDynamic([{ provide: AppSettings, useValue: new AppSettings(data.config) }]).bootstrapModule(AppModule);
});
});
UPDATE:
If you need to stick some values based on your env in to index.html you might need to consider doing that on your build server. You can rather string replace the values or you can have index.[env-name].thml files so you just overwrite the index.html based on environment build.
Also check out this issues
- https://github.com/angular/angular-cli/issues/7506
- https://github.com/angular/angular-cli/issues/3855

Templating in Electron?

Simple question here, but I found no useful resource. Is templating possible in Electron? Using Jade or Handlebars to display dynamic templates? I know there is .loadURL() that takes a static html file.
Is dynamic possible?
Thanks.
You could give electron-pug a chance. https://github.com/yan-foto/electron-pug
You can register a new buffer protocol via protocol.registerBufferProtocol.
main.js
var electron = require('electron');
var app = electron.app;
var protocol = electron.protocol;
var BrowserWindow = electron.BrowserWindow;
var pug = require('pug');
var window;
app.on('ready', function () {
// Define the `pug` scheme
protocol.registerBufferProtocol('pug', function (request, callback) {
var url = path.normalize(request.url.substr(7));
var content = pug.renderFile(url);
callback({
mimeType: 'text/html',
data: new Buffer(content)
});
});
window = new BrowserWindow({width: 600, height: 600});
// Load your file using the `pug` protocol
window.loadURL(url.format({
pathname: path.join(__dirname, 'index.pug'),
protocol: 'pug:',
slashes: true
}));
});
index.pug
html
head
title My title
body
h1 Hello world!
It would certainly be possible to use Jade or Handlebars for dynamic templating by running a local server in the Electron main process. I would not recommend this however, as it is kind of backwards. Electron is primarily a front end framework and while running a local server is good for some things, templating is not really one of them.
Most people use a frontend JS framework like Angular or React.
Probably too late to add here but thought it might be worthwhile. I have added a package to deal with adding views from any renderer and handle asset paths. So far I have just added the ejs renderer but plan on adding pug and haml as additional default renderers, but it is easy to extend and add your own as well. The package is called electron-view-renderer https://www.npmjs.com/package/electron-view-renderer
Hopefully this can help someone like it did our team. It is in its infancy, so all comments and contributions welcome
U can use ejs-electron to achieve the same purpose. U can check it out on github & simply install it as follows:
npm i ejs-electron --save
Just require it in ur main js file

Sails.js: Can I package some services/models as npm and load the npm in Sails.js app?

I want to create two different Sails.js app such as hello-world and hello-world-admin. In two app, I want to make two apps use same services/models. So I'm thinking that packaging services/models in hello-world app as a npm, and loading it in two.
But Sails.js models must be extended accordingly in lifting phase. So just using 'require' doesn't satisfy it at all. Is there any correct/good way to achieve it (using same models in two app)?
I'm thinking using hooks to extend models but I couldn't find good example. Any comments/info would be appreciated.
Updated
I'm trying to use "installable hooks" to extending models. I prepared sails-hook-models package in node_modules which has index.js below.
module.exports = function(sails) {
return {
defaults: {
},
initialize: function(cb) {
var ModelA = require('./models/ModelA');
ModelA.identity = 'modela';
ModelA.globalid = 'ModelA';
var ModelB = require('./models/ModelB');
ModelB.identity = 'modelb';
ModelB.globalid = 'ModelB';
sails.models['modela'] = ModelA;
sails.models['modelb'] = ModelB;
return cb();
},
};
After Sails has lifted, the models have been extended by waterline so I can call Model's method via sails.models['modela']. I'm not sure this is a good way.. Please tell me if you have alternatives / better ways.
Yes, and there is a way to do this already: https://github.com/tjwebb/sails-generate-entities. You define a manifest of which services/models/controllers/etc you'd like to install.
An example is here: https://github.com/tjwebb/sails-permissions
Yes, use the Sails Generator project to do this.

Sails.js -- Accessing local.js environment settings in controllers

In production I have AWS credentials stored as heroku config variables.
In development I want to include the config details in config/local.js, but how do I access the config details in a controller?
local.js contains:
module.exports = {
aws_key: "...", aws_secret: "..."
}
In my controller I have tried aws_key, config.aws_key, and others - but no luck. Is there a main app namespace that I can use to scope into the properties exported by local.js?
I am new to sails and I feel like this should be straight forward - any help would be appreciated.
Solution found. Step 3 was where I was having trouble.
tl;dr
What I didn't realize was that the module.exports.thing makes the thing object available through sails.config.thing. Good to know.
1) I created a new file at config/aws.js with the contents
// Get heroku config values
module.exports.aws = {
key: process.env.AWS_KEY,
secret: process.env.AWS_SECRET
}
2) In local.js put the actual AWS creds (this won't end up in the repository since sails automatically ignores local.js using gitignore).
aws: {
key: actual-key,
secret: actual-secret
}
This allows for local testing where we don't have access to the heroku config settings, while protecting these values from being exposed in a github repo.
3) Now, to access in the controller:
var aws_config = sails.config.aws;
AWS.config.update({
accessKeyId: aws_config.key,
secretAccessKey: aws_config.secret
});

sharing settings/config between client and backend

I have an application using node.js backend and require.js/backbone frontend.
My backend has a config/settings system, which depending on the environment (dev, production, beta) can do different things. I would like to propagate some of the variables to the client as well, and have them affect some template rendering (e.x change the Title or the URL of the pages).
What is the best way to achieve that?
I came up with a way to do it, and it seems to be working but I don't think its the smartest thing to do and I can't figure out how to make it work with requirejs optimizer anyway.
What I do is on the backend I expose an /api/config method (through GET) and on the client
I have the following module config.js:
// This module loads an environment config
// from the server through an API
define(function(require) {
var cfg = require('text!/api/config');
return $.parseJSON(cfg);
});
any page/module that needs config will just do:
var cfg = require('config');
As I said I am having problem with this approach, I can't compile/optimize my client code
with requirejs optimizer since /api/config file doesn't exist in offline during optimization. And I am sure there are many other reason my approach is a bad idea.
If you use use module bundlers such as webpack to bundle JavaScript files for usage in a browser, you can reuse your Node.js module for the client running in a browser. In other words, put your settings or configuration in Node.js modules, and share them between the backend and the client.
For example, you have the following settings in config.js:
Normal Node.js module: config.js
const MY_THIRD_PARTY_URL = 'https://a.third.party.url'
module.exports = { MY_THIRD_PARTY_URL }
Use the module in Node.js backend
const config = require('path-to-config.js')
console.log('My third party URL: ', config.MY_THIRD_PARTY_URL)
Share it in the client
import config from 'path-to-config.js'
console.log('My third party URL: ', config.MY_THIRD_PARTY_URL)
I do the following (note that this is Jade, i have never used require.js or backbone, however as long as you can pass variables from express into your templating language, you should be able to place JSON in data-* attributes on any element you want.)
// app.js
app.get('/', function(req, res){
var bar = {
a: "b",
c: Math.floor(Math.random()*5),
};
res.locals.foo = JSON.stringify(bar);
res.render('some-jade-template');
});
// some-jade-template.jade
!!!
html
head
script(type="text/javascript"
, src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js")
script(type="text/javascript")
$.ready(init);
function init(){
var json = $('body').attr('data-stackoverflowquestion');
var obj = JSON.parse(json);
console.log(obj);
};
body(data-stackoverflowquestion=locals.foo)
h4 Passing data with data-* attributes example

Categories