How can I pass a variable while using `require` in node.js? - node.js

In my app.js I have below 3 lines.
var database = require('./database.js');
var client = database.client
var user = require('./user.js');
user.js file looks just like ordinary helper methods. But, it needs interact with database.
user.js
exports.find = function(id){
//client.query.....
}
Apparently, I want to use client inside of the user.js file. Is there anyway that I can pass this client to the user.js file, while I am using require method?

I think what you want to do is:
var user = require('./user')(client)
This enables you to have client as a parameter in each function in your module
or as module scope variable like this:
module.exports = function(client){
...
}

This question is similar to: Inheriting through Module.exports in node
Specifically answering your question:
module.client = require('./database.js').client;
var user = require('./user.js');
In user.js:
exports.find = function(id){
// you can do:
// module.parent.client.query.....
}

You should just put the same code in user.js
app.js
var client = require('./database.js').client; // if you need client here at all
var user = require('./user.js');
user.js
var client= require('./database.js').client;
exports.find = function(id){
//client.query.....
}
I don't see any drawbacks by doing it like this...

Why do you use require, for scr, no prom use source. It's the same as require and we can pass args in this fuction.
var x="hello i am you";
console.log(require(x)); //error
console.log(source(x)); //it will run without error

Related

How to use module in my own node js module?

How I can use third party module in my own? For example if I have in app main file something like (using body-parser):
app.post("/dothis", (req,res)=>{
var name = req.body.name;
console.log(name);
};
This work fine. But when I want to have this in separate file (for example mod.js), and wrote like this:
exports.own = function(){
var name = req.body.name;
console.log(name);
}
Then in main file wrote:
const mod = require(__dirname + "/mod.js")
app.post("/dothis", (req,res)=>{
mod.own();
};
Then I get error like, req is undefined.
I am trying to add in mod.js file
const {req} = require ("http");
So then I got error that can't read value of name undefined.
There is the question, how i can transfer my code which is using body-parser, express and other modules to separate file or creating own module to get working module?
Thanks!
You are getting undefined because you are not passing the request.
Looking at your code, try this.
exports.own = function(req){ // use request
var name = req.body.name;
console.log(name);
}
const mod = require(__dirname + "/mod.js")
app.post("/dothis", (req,res)=>{
mod.own(req); // pass request
};

getting api keys from module.exports

I have two files a config.js and main.js I am storing api keys in my config.js
like this
function getGoogleApiKey(){
return 'KeyGoogle';
}
function getApiKey(){
return 'keyApi'
}
function getApiKey2(){
return 'keyApi2'
}
module.exports = {
getGoogleApiKey,
getApiKey,
getApiKey2,
}
I would like to get specific keys from the config.js file when I need it. I want to use some keys on my main.js
Here is my main.js.
const {config} = require('./config.js');
const googlePlaces = new GooglePlaces(config.getGoogleApiKey, 'json');
const awesome = new awesome(config.getApiKey);
I am note sure how to get the keys, I also tried it in this way but I get errors.
const {getGoogleApiKey, getApiKey, getApiKey2} = require('./config.js');
const googlePlaces = new GooglePlaces(getGoogleApiKey, 'json');
This line:
const {config} = require('./config.js');
is pulling out a config property from the value returned by require('./config.js'), which is non-existent in config.js.
Instead, just use this:
const config = require('./config.js');
which will assign the exported value (the module.exports object), and will work as expected.
Secondly, functions are being exported and not primitive (string) properties, so one or the other will need to be changed: export string properties directly or convert main.js to use the appropriate function call notation.
For example:
const googlePlaces = new GooglePlaces(config.getGoogleApiKey(), 'json');
const awesome = new awesome(config.getApiKey());

Two way communication between routers within express app

I have an express app that has a router for different sections of my application, each contained within individual files. At the end of each file I export the router object like so.
var express = require("express");
var router = express.Router();
//routing handlers
module.exports = router;
However my problem is that I am trying to implement a feature were a user is allowed to edit a post that could be displayed on the front page, therefore in order to have the most current version of the user's post I need to be able to know when the user edits the post to make the necessary changes.
I have two modules one that handles dispatching the user's posts call this module B and another that handles editing call this module A. I need to be able to have module A include handler function and an array from module B, but I also need module B to be able to be notified when to make changes to the its array that module A requires.
I have tried
module A
var express = require('express');
var EventEmitter = require('events').EventEmitter;
var evt = new EventEmitter();
var router = express.Router();
var modB = require('moduleB');
router.evt = evt;
module.exports = router;
Module B
var express = require('express');
var router = express.Router();
var modA = require('moduleA').evt;
modA.on('myEvent',handler);
var myArray = [....];
router.myArray = myArray;
module.exports = router;
This gives me an undefined for modA and throws an error. I suspect it might be the order the modules are included but anyhow I would like to obtain some feedback since I sense that this might not even be good practice.
I think you are running into a common scenario for someone just starting out with express. A lot of people stick everything into routes/controllers when really the route should be very simple and just extract the data needed to figure out what the request is doing and then pass it to a service for most of the processing.
The solution is to create a Service and put the bulk of your logic and common code there, then you can wire up ModA and ModB to use the Service as needed.
EDIT with an example(not working but should give you a good starting point):
Shared Service
var EventEmitter = require('events').EventEmitter;
var evt = new EventEmitter();
module.exports = {
saveData: function(data) {
// do some saving stuff then trigger the event
evt.emit('myEvent', data);
},
onDataChange: function(handler) {
evt.on('myEvent', handler);
}
};
Module A
var service = require('SharedService.js');
// listen for events
service.onDataChange(function(e, data) {
// do something with the data
});
Module B
var service = require('SharedService.js');
// save some data which will cause Module A's listener to fire
service.saveData(data);
This example above hides the implementation of EventEmitter which may or may not be desirable. Another way you could do it would be to have SharedService extend EventEmitter, then your Modules could listen/emit directly on the service.

how to mock twilio in unit tests with either sinon/proxyquire or dependency inejction in node.js

Say I want to test a a user login controller that sends login codes via SMS with Twilio. How should I set up the test so that I can mock Twilio and see what codes it's sending back. My approach was to proxyquire the twilio client object and spy on it with sinon, but I don't think I'm getting it quite right.
controller user.js
var smsClient = new twilio.RestClient(config.get('twilio_account_sid'), config.get('twilio_auth_token'));
module.exports = {
checkCode: function(phone){
var code = getNewCode();
smsClient.sms.messages.create({
from: config.get('twilio_phone_number'),
to: phone,
body: 'Your code :' + code
}, callback);
}
}
test file
var twilioMock = //what goes here??
var smsSpy = sinon.spy(twilioMock.sms.messages, 'create');
var User = proxyquire('../models/user', { 'mongoose': mongooseMock, 'smsClient': twilioMock });
... some describe and it statements ...
twilioMock.sms.messages.should.have.been.calledOnce() //this is where I don't know what I should be checking
// or is this the right way?
//smsSpy.should.have.been.calledOnce()
I am answering this very late but this might help someone.
I haven't used proxywire but it seems very similar to rewire (just by looking at your code). You should try the following:
var twilioMock = new twilio.RestClient(config.get('twilio_account_sid'), config.get('twilio_auth_token'));
I am more used to rewire. npm i rewire --save-dev. Using rewire you may try the following: (concept remains the same)
In your test:
var rewire = require('rewire');
var twilioMock = new twilio.RestClient(config.get('twilio_account_sid'), config.get('twilio_auth_token'));
var userController = rewire('./path_to_user.js') // notice use of rewire
beforeEach(function(){
this.smsClient = twilioMock; // `this` is available within your tests
userController.__set__('smsClient', this.smsClient);
});
it('should something', sinon.test(function(){
var smsSpy = this.spy(this.smsClient.sms.messages, 'create');
}));

Hierarchical routing with plain Express.js

I’m implementing a RESTful API using Node and Express. When it comes to routing, currently it looks like this:
var cat = new CatModel();
var dog = new DogModel();
app.route('/cats').get(cat.index);
app.route('/cats/:id').get(cat.show).post(cat.new).put(cat.update);
app.route('/dogs').get(dog.index);
app.route('/dogs/:id').get(dog.show).post(dog.new).put(dog.update);
I don’t like this for two reasons:
Both cat and dog models are instantiated whether I need them or not.
I have to repeat /cats and /dogs for every path schema
I’d love to have something like this (not working, of course):
app.route('/cats', function(req, res)
{
var cat = new CatModel();
this.route('/').get(cat.index);
this.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});
app.route('/dogs', function(req, res)
{
var dog = new DogModel();
this.route('/').get(dog.index);
this.route('/:id').get(dog.show).post(dog.new).put(dog.update);
});
Is there a clean way in modern Express without any further modules (like express-namespace)? I could go for separate routers for each model and assigning them with app.use('/cats', catRouter). However, what if I have more than one hierarchy level like '/tools/hammers/:id'? I would then have routers within routers within routers, which seems like overkill to me.
I would then have routers within routers within routers, which seems like overkill to me.
Perhaps, but that is the built-in method of prefixing -- to app.use() a Router().
var cats = express.Router();
app.use('/cats', cats);
cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
// ...
And, to have one Router .use() another to define multiple depths:
var tools = express.Router();
app.use('/tools', tools);
var hammers = express.Router();
tools.use('/hammers', hammers);
// effectively: '/tools/hammers/:id'
hammers.route('/:id').get(...);
Though, to be closer to your 2nd snippet, you can define a custom method:
var express = require('express');
express.application.prefix = express.Router.prefix = function (path, configure) {
var router = express.Router();
this.use(path, router);
configure(router);
return router;
};
var app = express();
app.prefix('/cats', function (cats) {
cats.route('/').get(cat.index);
cats.route('/:id').get(cat.show).post(cat.new).put(cat.update);
});
app.prefix('/dogs', ...);
app.prefix('/tools', function (tools) {
tools.prefix('/hammers', function (hammers) {
hammers.route('/:id').get(...);
});
});
Check out the new Router in Express 4. It sounds exactly what you're looking for.

Resources