Nodejs set command line argument as constant - javascript

I want to get an argv from my command line when I am going to start my server and then I want to set it as a constant for a module.
For example I want to define my log file path from commandline:
My starter.js looks like:
var optimist = require("optimist");
var server = require("./start_server");
var argv = optimist.describe('logpath', 'logptah for info').argv;
server.init({logpath:argv.logpath});
My start_server.js looks like:
var restify = require('restify');
var server = restify.createServer({
name: 'dummy-project'
});
module.exports.logpath = null;
function init(args){
server.listen(1234, function() {
console.log("inside logs");
console.log(args.logpath);
module.exports.logpath = args.logpath;
console.log('%s listening at %s', server.name, server.url);
});
};
module.exports.init = init;
var fun = require('./common/loghandler');
My loghandler.js looks like:
var server = require('./../start_server');
console.log("inside log handler");
var LOGPATH = server.logpath;
console.log(LOGPATH);
When I am running node starter.js --logpath='../../custom/info.txt'
I am not getting the logpath inside my loghandler.
Seems logpath handler is called before the server.listen.
The console output looks like:
node starter.js --logpath='../../custom/info.txt'
inside log handler
null
inside log handler
../../custom/info.txt
dummy-project listening at http://0.0.0.0:1234
How I can overcome it and pass my log path as command line argument?
Thanks in advance.

Your init() function is executed after starter.js uses require('./start_server'). When you use require(), the file and all its dependencies are loaded. That means during this process, you also executed require('./common/loghandler'), which completes before server.init() is run in starter.js. Since server.logpath hasn't been set by this time, you get a null value.
Aside from that, module.exports is set at require time and changing the values later have no effect. To fix the problems you're having, you should avoid using functions before your application has fully loaded, and put return values in your modules.

Related

Running python script from MagicMirror module

I am currently developing a custom module for my magic mirror.
I want this module to execute a python script.
This python script fetches data from a web server and creates a .json file in the module folder with the data.
I then want the module to import this datafile inside javascript and display it on screen.
However i cant get the magic mirror module to run the python script.
I have very little javascript knowledge so any help is appreciated.
This is the code i have so far
defaults: {
},
start: function () {
var timer = setInterval(()=>{
const spawn = require('child_process').spawn;
const childPython = spawn('python3', ['./modules/MMM-Test/bussavganger.py']);
this.updateDom()
}, 5000)
},
getDom: function() {
var element = document.createElement("div")
element.className = "myContent"
element.innerHTML = "Hello, everybody!"
return element
}
})
Currently i am just trying to run the module to see if the .json file is created. it is not.
If i run the python script separately the file is created, so i know the .py file is not the problem.
You tried calling the python script via your module's js file, but instead you should use to call the python script via the node_helper.js file.
So use the socketNotification function of the MagicMirror to call the noder_helper and in return the node_helper then calls your python script, you can do something with it and at the end send back a socketNotification to your module's js file, e. g. the result of your python program or the exit code, etc.
In your start: function() you could call the node_helper via this command, so that your python program is being started by the module helper later directly after booting up your module (doing that from now on every interval):
var self = this;
setInterval(function() {
self.sendSocketNotification('DO_PYTHON', <transmit data for your node_helper here>);
self.updateDom();
}, 5000);
Create a node_helper.js file in your module folder with the following:
var NodeHelper = require("node_helper");
const spawn = require("child_process").spawn;
module.exports = NodeHelper.create({
init() {
},
start() {
},
stop() {
},
// If notification of the main.js file is received, the node_helper will do this here:
socketNotificationReceived(notification, payload) {
if (notification === "DO_PYTHON") {
// this.config = payload;
this.yourOwnMethod();
} else {
// ...
}
},
yourOwnMethod() {
var self = this;
var process = spawn("python3", ["/absolute/path/to/modules/MMM-Test/bussavganger.py"]);
// do something else here
this.sendSocketNotification("PYTHON_DONE", <e. g. exit state as your payload>)
},
You can read in your json file with fs in the node_helper.js as well and parse it there and send it back via the sendSocketNotification.
Be sure to have included the two beginning lines in the node_helper.js and (!) important use always absolute paths.

How to get value from modified object in Node.js

how to get modified value of object? index.js is called before index2.js
object.js
var object = {
size:'5'
};
var setSize = function(size) {
object.size = size;
}
exports.object = object;
exports.setSize = setSize;
index.js
var obj = require('path/object');
obj.setSize('10');
console.log(obj.object.size); //--> 10
index2.js
I want the result to be 10.
var obj = require('path/object');
console.log(obj.object.size); //--> 5
If you run node index.js separately from node index2.js, there is no way for index2.js to "know" what happened in the last process of index.js. You have to apply all your actions in a single process run. As #Andrew Li stated in his comment, you would have to require index.js in your index2.js. Simply requiring it, will have it's code executed and the changes to obj.object will be saved in Nodes module caching mechanism.
var obj = require('path/object');
require('./index');
// code inside index.js gets executed, changing obj.size to '10'
// note that this will also log '10' in the console, since a console.log(obj.size)
// is part of your code in index.js
console.log(obj.object.size) //--> 10
If you need to have index.js and index2.js executed in different processes but still be able to access a coherent value of obj, you need to store that value somewhere outside of the process space, like in a database or in the filesystem.

Prevent onComplete exit in Jasmine

I would like to make multiple calls of test function, but after first time, that jasmine.onComplete is called, the programs exits. I already know, that I can't do multiple test in parallel, but I thought, that I may be able to queue them, but if the jasmine exit the node I am done. Therefor:
Is there a way to prevent jasmine to exit node?
const toCall = {}
jasmine.onComplete(function(passed) {
toCall[varReporter.last.name](passed, varReporter.last.result)
toCall[varReporter.last.name] = null
});
function test(folder, file, callback){
toCall[file] = callback
jasmine.execute(['JS/' + folder + '/tests/' + file + '.js'])
}
// User saves a file, a test get triggered.
test('prototype', 'Array', function(passed, result){
console.log(util.inspect(result, { colors: true, depth: null }))
})
// User saves an other file and an other test should get triggered, but can't.
My test will not be called in groups, but one after an other, based on users interactions with files. I need to run test after each save, so that I can determine whenever I should process them or not.
You could override jasmine exit option:
jasmine.exit = () => {};
But that causes various glitches.
I'd rather run whole script in another process:
run-test.js
const path = require('path'),
Jasmine = require('jasmine/lib/jasmine.js');
const jasmine = new Jasmine({ projectBaseDir: path.resolve() });
jasmine.execute(process.argv.slice(2));
watch-tests.js
const fork = require('child_process').fork;
function test(folder, file) {
fork('run-test.js', ['JS/' + folder + '/tests/' + file + '.js']);
}
// User saves a file, a test get triggered.
test('prototype', 'Array')
// User saves an other file and an other test should get triggered, but can't.

scribe js error - console.log not defined

I was using scribe js like
app.js
var scribe = require('scribe-js')();
var console=process.console;
app.use(scribe.express.logger());
app.use('/logs', scribe.webPanel());
and in my
module.js
var like = 0;
var error=require('./error');
var console=process.console; <-- this line
//only works if i comment above line
//else it shows console not defined
var like_dislike = {
like: function(req, res, next) {
like++;
console.log(process.console);
console.log("Like:" + like + " ClientTime:" + req.query.timestamp);
res.sendStatus(200)
}
}
module.exports=like_dislike
Any Idea, atleast where to start looking to resolve this ?
Thanks
EDIT
error.js
function error(res, custom_error, actual_error) {
if (actual_error)
console.error(actual_error);
res.status(custom_error.status).send(custom_error.text);
}
module.exports=error;
The problem is that the express router does not maintain a reference to the console variable (or process, it seems) while passing the request along to the handler. This problem persists even you you try to use the console variable inside an anonymous handler in the same file (not loading a submodule).
The solution is to cache a reference to Scribes console in app.locals and access it via req.app.locals.console. More details at this question: Global Variable in app.js accessible in routes?
I sent you a pull request on github. the updates that I have made are marked with comments in the style of:
/*
* update explination
*/

How can I run two files in javascript with node?

I am new to javascript and Node.js and having problems testing some code I wrote recently. I am trying to test code written in a file called "compareCrowe.js" with "testCrowe.js" using Node.js.
Here are the contents of testCrowe.js:
var compareCrowe = required['./compareCrowe'];
console.log('begin test');
var connection = {Type:1, Label:"label", linkTo:null};
var table1 = {name:"table1", body:"description1", out:[connection]};
var table2 = {name:"table2", body:"description2", out:null};
connection.linkTo = table2;
var crowe = [table1, table2];
var result = compareCrowe.compareCrowesFoot(crowe, crowe);
console.log(result.feedback);
where the function "compareCrowesFoot" is defined in compareCrowe.js. From the console on an Ubuntu virtual machine I ran:
node compareCrowe.js testCrowe.js
however, nothing was printed. There were no errors or warnings or explanation of any kind. It didn't even print the "begin test" line I placed at the top of testCrowe.js. If I run the command:
node testCrowe.js
it complains that compareCrowesFoot is undefined. How can I test the contents of compareCrowe.js?
Welcome to the party of JS.
I'm not sure where you're learning from, but a few of the resources that have helped me and many others are superherojs.com, nodeschool.io, the MDN developer docs, Node.js API docs, and Youtube (seriously).
The basic idea of Node.js is that it operates with modules (chunks of reusable code), which is what NPM is made up of. These can then be included in other modules and used anywhere else in your application.
So for a basic example, say you had compareCrowe.js, to make it includable/reusable in another file, you could write something like:
module.exports = function() {
var compareCrowesFoot = function(crowe1, crowe2) { /* compare crows feet and return something here */ }
return { compareCrowesFoot: compareCrowesFoot };
// return an object with a property of whatever you want to access it as , and the value as your function name
// e.g. - you could return { compare: compareCrowesFoot };
}
Then in testCrowe.js you could require compareCrowe like this:
var compareCrowe = require("./compareCrowe");
/* your code here... */
var result = compareCrowe.compareCrowesFoot(crowe1, crowe2);
// if your returned object was { compare: compareCrowesFoot };
// this would be compareCrowe.compare(crowe1, crowe1);
And to run your tests, you could then run node testCrowe.js from the command line.
In your case it seems like you've got your syntax a little messed up. It should be more like:
var compareCrowe = require('./compareCrowe.js');
That would make any methods you've exported in compareCrowe.js, such as your compareCrowe.compareCrowesFoot function, available to testCrowe.js.
Then, in your terminal, you would run the following:
node testCrowe.js
And that should do the trick provided you don't have any further errors in your code.

Categories

Resources