How to automigrate when needed in loopback 3? - node.js

I created an automigrate script under /bin in my loopback app and added its path in the package.json file so that I can run this script to automigrate whenever I want from the terminal.
I also have a boot script "createUsers.js" which creates some default users in a model. The problem is, whenever I run this script it calls the boot script and it tries to create the users while automigration is still not finished, resulting in a failed automigration. I don't understand why the boot scripts are called when I only run automigrate script specifically. I could call automigrate in the boot scripts and wrap the createUsers.js code in its callback (as shown here), but that would automigrate every time the app is started which is undesirable since the data is lost on automigration. Where should I call automigrate() so that it can be called whenever required? Any help is greatly appreciated.

What I normally do, is create a script called util.js inside boot
util.js
class util{
static _automigrate(){
//Whatever you need to do
}
}
module.exports = function (server) {
global.util = util;
};
This way your script is available across the entire application. And you can call it whenever you need to.
You could call it with
util._automigrate();
I normally use this pattern to store all my input validations etc since I might need those across different models.

Related

How do I invoke a Sails.js controller function from a file in the project root?

I am building a Sails.js application that runs on Heroku. I need to use Heroku Scheduler to run a "CRON" job every few hours. The scheduler only allows me to run a single command so I have it setup to run $ node sendEmails.js every 1 hour.
The issue is, sendEmails.js is not a part of the core Sails.js project and I need it to invoke a function inside my ReportsController.js file. How exactly do I go about doing this? I don't want to copy the controller logic to sendEmails.js because it has a lot of dependencies to the database and other services which I can't duplicate. For context:
/**
* ReportsController
*
* #description Server-side logic for managing reports
* #help See http://sailsjs.org/#!/documentation/concepts/Controllers
*/
module.exports = {
// I need to call this function from sendEmails.js which is in my project root
generate: function(req, res) {
// Logic for generating reports
}
}
You can do this in several ways:
(Better) Create a service and then invoke the service name like Myservice.myfunction or even sails.myservice.function. Your service, as the name says, will be available for every controller and can be used to centralize code that will be used globally. Take a look : Sails Services. You can then invoke your service inside a controller, then your service can (or cannot) do option 2 if it suits you.
(Not very good) Inside a controller or service, do a manual require for the path of your file. Like this let myfunctions = require('../folder/myfile.js') and then invoke the functions like ``myfunctions.myfunction(nargs). Don't forget to usemodule.exports = {...}`.

How to run javascript outside of router function in Foxx

I would like to do some variable toggling for dev and prod production but it seemed like If..else does not run outside of router code. Am I doing something wrong?
//Other variable declare above
//This one wont run
if(isDev){
coll=db._collection("DevColl")
}
else{
coll=db._collection("ProdColl");
}
//////////////////////////////////
//Later use coll in the router code
router.get("/"),function{
}
Please note that ArangoDB starts several Javascript V8 contexts (they call this "Isolate") while NodeJS just has one.
During the lifecycle of ArangoDB new Isolates may be spawned, and old ones flushed. Global objects in Isolates that are not being referenced may be removed to save memory.
Thus there is no direct way to have global setting inside of javascript.
However, there are three possible ways to achieve this:
A collection that can switch the state (may be slow in production too...)
using the system environment via process.env which you then would have to set in the initscripts starting ArangoDB.
install another instance of your foxx service, access the collections via module.context.collection()

How to automatically run .sh after a file is uploaded

I am new to Sails/nodeJS. I am trying to create a system that will automatically run a .sh after a video is uploaded to the server (local file system). I understand from Sails documentation that file uploading is done in Controller file, and what I want to do is to trigger a .sh after that. I need to constantly read the output from .sh and return it to the backend.
Anyone has any idea how to implement this?
Thanks!
You always can use https://www.npmjs.com/package/exec
Simple implementation:
var exec = require('exec');
exec('PATH TO YOUR .SH FILE', function(err, out, code) {
// Process to the next action within the callback function.
});

Grunt - Is it possible to have a task that only runs once ever?

There is a particular task that I want to run only once and then guarantee that it is never run again. Has anyone done this? I was looking at using grunt.event.once(...), or try and detect folders or files using a shell script on postinstall, but both ways leave a task in the gruntfile.js that could potentially be invoked at any time overwriting files.
At a very simple level it would do something like this:
grunt.registerTask('setup', [
'mkdir' // run some setup tasks
]);
grunt.event.once('setup', function() {
// some how do what's below here so it can't be done again
// so not available in config for reuse and possibly overwriting
// modified files
grunt.task.run([
'bowercopy:src_codeigniter'
]);
});
This even possible in Grunt? I know it's just a task runner, in this case I just want it to run it once.
There are several libraries that let you access a Gruntfile's content via an API so you could use one of these to alter your setup task's configuration after it is run the first time.
There's Gruntfile Editor and Gruntfile API
While both of them don't support complete task removal you can always modify your tasks configuration this way.

Working with Node.JS

Last night I dump windows 7 and formatted my hard driver to port to a Linux based operating system, Purely for the reasons that I wanted to start working with Node.JS
So I have installed Node.JS and have done a few test stuff, the http server and sockets etc.
What I would like to do is build a HTTP Server that is tightly intergrated with an MVC Framework, but before I get started on all that I need to learn how to build efficiently in Node.
For example within PHP as my framework I would create a bootloading system to load all base classes etc, then i would fire my events system ready to start attaching callbacks.
I would continue to process the request etc until the output is generated which then gets sent of to an output handler that would process headers etc etc
But Node s a totally new environment for this and im wondering on the best practises to build an system in Node.
The information im looking for is more to do with the design structure rather then the actual coding of the application, how to load the lib where to load the libs, etc etc
Any help is appreciated.
So far my WebApplication is coming along nicely, I have built my application pretty traditionally and a little procedural.
What i have started out is creating a directory structure like so:
<root>
startup.js
/public/
favicon.ico
/images/
/stylesheets/
/javascripts/
/system/
init.js
config.js
/libs/
/exceptions/
http.js
server.js
/application/
/views/
/_override/
/errors/
generic.view
/partials/
sidebar.voew
index.view
/controllers/
index.js
/models/
users.js
This directory structure is like most MVC Based Web Applications out there so using this method I feel comfortable.
The startup file is whats executed by node as the entry point, node startup & and looks like so:
/*
* Header of t he file, Copyright etc
*/
var _Intitialize = require("./system/init.js");
//Displays the command line header, title, copyright etc
_Intitialize.DisplayCommandLineHeader();
//Check the enviroment, Permissions, Ports etc
_Intitialize.CheckEnviroment();
//Start the server and listen the port.
_Initialize.StartServer();
the init file is the main work, its what tells all other areas of the system to run, stop etc.
I have a file in libs called serverhandler.js, and this is required into init.js, I then create a server and assign the callback to the ServerHandler.Listener. Who then listens for requests, checks to see if the file exists in public directory, if so it then reads in chunks and sends back.
if no file was found in public it would then create a route with Route.Create("/path?params"); which deters 3 elements, Controller, Method, Params from the uri, and then the controller files are loaded if exists.
I've taken on the approach of throwing error pages like so:
if(!FileSystem.exists(RequiredPath))
{
throw new HTTPExceptions.FileNotFound();
}
Hope this helps some people getting started in Node.
Have a look at
http://dailyjs.com/2010/11/01/node-tutorial/ , it's pretty relevant.
I would suggest looking at the current modules too
https://github.com/joyent/node/wiki/modules
and reading the code of any of the projects in the areas you are interested in, esp. the middleware, routing and module loaders.

Resources