Accessing the callback from a node module - node.js

simple Q: How do I access the callback from rimraf? See here.
Can't wrap my head around how to structure the code - I'm trying for example:
var rimraf = require('rimraf');
var removeDir = rimraf(p, callback);
var p = 'docs/mydirectory';
removeDir(p, function(cb){
console.log(cb)
});
But receiving callback undefined.. I'm probably doing something completely wrong! Can someone point me in the right direction? Cheers

var removeDir = rimraf(p, callback);
Is calling the rimraf function, not setting a reference to it. If you want to call it removeDir then use it instead...
var removeDir = require('rimraf');
var p = 'docs/mydirectory';
removeDir(p, function(err){
console.log('dir removed');
});

Related

SINON unittesting stub constructor

I'm trying to stub a constructor in node but I really can't.
I found this , that is quite similiar to what I need to do but I have an error that I could not solve.
//file.js
var foo = require('foo-client')
function toTest () {
var bar = foo()
returns config = bar.foo2(a,b) // returns a Promise
}
what I am trying to do in the test file is
//file-sepc.js
var stub = sinon.stub()
stub.returns(Promise.resolve('config'))// config it's just an example
var file = proxyquire('./file.js', {
'foo-client':{foo2: stub}
})
file.toTest()
.then((result) => {
console.log(result)
done()
})
supposing the node syntax is correct, I am getting this output:
TypeError: foo is not a function
Can anyone help me telling me where is my error or another way to mock/stub this things?
Thanks a lot!
Haven't tried running your code but it looks like foo-client should be a function rather than an object in order for the var bar = foo() not to throw an error you are seeing. Try the following:
var file = proxyquire('./file.js', {'foo-client': sinon.stub.returns({ foo2: stub }) })

Exporting a new object in Node.js

How can I pass the variables port,host,database into this function?
//myjs.js
var redisCaller = function(port,host,database){
};
module.exports = new redisCaller();
if I do:
var myjs = require('./myjs');
how do I pass those variables?
seems like the only way to do it is like this:
module.exports = function(port,host,database){
return new redisCaller(port,host,database);
}
Change myjs.js to:
module.exports = redisCaller;
Then you can do:
var myjs = require('./myjs')(port,host,database);
You don't.
The way you've set up that code makes it impossible to pass variables in, unless you tweak the require. Which then makes you potentially have to know about the port/host/database in any file you use it in.
Instead, maybe just use an 'init'.
For example, app.js -
var redisCaller = require('./myjs');
redisCaller.init(port, host, database);
And the myjs..
var redisCaller = function(){
this.init = function (port,host,database) {
this.connection = ...
}
this.getConnection = function () {
if(!this.connection) { throw "Need to run init first"; }
return this.connection;
}
};
module.exports = new redisCaller();
Anywhere you need the connection...
var redisCaller = require('./myjs');
var conn = redisCaller.getConnection();
//or
var redisCaller = require('./myjs').getConnection();
It's a bit more code, but at least it's easy to reuse across files.. assuming that was your intention.

pass optional parameters to require()

so, I have this problem - and when I have a problem with JavaScript or node inevitably it is my coding that is the problem ;)
So at the risk of ridicule, this is the problem:
I have a module that has an optional parameter for config
Using the standard pattern, this is what I have:
module.exports = function(opts){
return {
// module instance
};
}
and in the calling code there is this
var foo = require('bar')({option: value})
if there are no options to pass, the code looks like this
var foo = require('bar')({})
which kinda looks ugly
so, I wanted to do this
var foo = require('bar')
which doesn't work, as the exports is a function call
so, to the meat of the issue
a) is there any way of achieving this lofty goal ?
b) is there a better pattern of passing parameters to a module ?
many thanks - and I hope that once the laughter has passed you will be able to send some help my way :)
Instead of removing the function call completely, you could make the options argument options to remove the need for an empty object:
module.exports = function(opts) {
opts = opts || {};
return {
// module instance
};
}
It doesn't completely remove the need for () but is better than ({}).
tldr: stick with require('foo')('bar');
There's no way to pass additional parameters to require. Here's the source code, notice how it only takes a single argument:
Module.prototype.require = function(path) {
assert(util.isString(path), 'path must be a string');
assert(path, 'missing path');
return Module._load(path, this);
};
If you really really really want to avoid ()(), you could try something like this:
b.js
'use strict';
module.exports = {
x: 'default',
configure: function (x) {
this.x = x;
},
doStuff: function () {
return 'x is ' + this.x;
}
};
a.js
'use strict';
var b = require('./b');
// Default config:
console.log(b.doStuff()); // 'x is default'
// Reconfigure:
b.configure(42);
console.log(b.doStuff()); // 'x is 42'
But I think it's uglier... stick with the original idea.

Node.JS - fs.exists not working?

I'm a beginner in Node.js, and was having trouble with this piece of code.
var fs = require('fs');
Framework.Router = function() {
this.run = function(req, res) {
fs.exists(global.info.controller_file, function(exists) {
if (exists) {
// Here's the problem
res.writeHead(200, {'Content-Type':'text/html'});
var cname = App.ucfirst(global.info.controller)+'Controller';
var c = require(global.info.controller_file);
var c = new App[cname]();
var action = global.info.action;
c[action].apply(global.info.action, global.info.params);
res.end();
} else {
App.notFound();
return false;
}
});
}
};
The problem lies in the part after checking if the 'global.info.controller_file' exists, I can't seem to get the code to work properly inside the: if (exists) { ... NOT WORKING }
I tried logging out the values for all the variables in that section, and they have their expected values, however the line: c[action].apply(global.info.action, global.info.params);
is not running as expected. It is supposed to call a function in the controller_file and is supposed to do a simple res.write('hello world');. I wasn't having this problem before I started checking for the file using fs.exists. Everything inside the if statement, worked perfectly fine before this check.
Why is the code not running as expected? Why does the request just time out?
Does it have something to do with the whole synchronous vs asynchronous thing? (Sorry, I'm a complete beginner)
Thank you
Like others have commented, I would suggest you rewrite your code to bring it more in-line with the Node.js design patterns, then see if your problem still exists. In the meantime, here's something which may help:
The advice about not using require dynamically at "run time" should be heeded, and calling fs.exists() on every request is tremendously wasteful. However, say you want to load all *.js files in a directory (perhaps a "controllers" directory). This is best accomplished using an index.js file.
For example, save the following as app/controllers/index.js
var fs = require('fs');
var files = fs.readdirSync(__dirname);
var dotJs = /\.js$/;
for (var i in files) {
if (files[i] !== 'index.js' && dotJs.test(files[i]))
exports[files[i].replace(dotJs, '')] = require('./' + files[i]);
}
Then, at the start of app/router.js, add:
var controllers = require('./controllers');
Now you can access the app/controllers/test.js module by using controllers.test. So, instead of:
fs.exists(controllerFile, function (exists) {
if (exists) {
...
}
});
simply:
if (controllers[controllerName]) {
...
}
This way you can retain the dynamic functionality you desire without unnecessary disk IO.

How should I pass options to a node module?

If I have a node module (I wrote) and I want to pass it a value, I could do this:
var someValue process.env.SomeKey || '';
var someModule = require('./someModule');
someModule.setOption({ 'SomeKey' : someValue });
but it feels like I am reinventing the wheel.
Is there a better way to do this or is it totally subjective?
In general, you simply export a function from the module:
module.exports = function(opts){
return {
// module instance
};
}
then in the requiring page:
var mod = require('module')({ someOpt: 'val' });
But in reality, do it however you want. There's no set-in-stone standard.
I generally build modules that have similar components, sometimes just one class, or even just a selections of methods.
(function () {
var myClass = function (opts) {
this.opts = opts;
};
myClass.prototype.blah = function () {
console.log('blah');
};
exports.myClass = myClass;
})();
Then in your file that is using that module.
var mymodule = require('./mymodule');
var myInstance = new mymodule.myClass({opt1: 'blah'});
myInstance.blah();
Of course you don't need to just pass around an object of options :)
Yes, it is totally subjective.
Doing it the way you demonstrated is fine. You can also just export a function or a class by assigning it to module.exports.

Resources