Different results using Node.js' module.exports in Yeoman - node.js

I am receiving different results with module.exports and would appreciate someone helping me shore up the obvious hole in my knowledge.
From the following code, I receive the result listed below it.
var generators = require('yeoman-generator');
var MyBase = generators.Base.extend({
helper: function() {
console.log('this is a helper method');
}
});
module.exports = MyBase.extend({
method1: function() {
console.log('method 1 just ran');
}
});
Result:
method 1 just ran
But if I place module.exports on its own line, and assign MyBase to it, I get the following result. Here is the code:
var generators = require('yeoman-generator');
var MyBase = generators.Base.extend({
helper: function() {
console.log('this is a helper method');
}
});
MyBase.extend({
method1: function() {
console.log('method 1 just ran');
}
});
module.exports = MyBase
Result:
this is a helper method
What is causing the difference in outputs?

I haven't been able to completely reproduce your issue, but the problem is almost certainly the fact that calling .extend on a generator returns a new generator with both the current and extended properties.
var generators = require('yeoman-generator');
var MyBase = generators.Base.extend({
helper: function() {
console.log('this is a helper method');
}
});
// Capture the output of the .extend function
var MyBase2 = MyBase.extend({
method1: function() {
console.log('method 1 just ran');
}
});
module.exports = MyBase2
Alternatively, you could just define multiple properties in one go
var MyBase = generators.Base.extend({
helper: function() {
console.log('this is a helper method');
},
method1: function() {
console.log('method 1 just ran');
}
});

Related

Gather multiple functions output on single route call and render to html in nodejs

Newbie to nodejs,trying to execute multiple functions output to html using nodejs,express and mysql as backend.Need to execute 20 functions on single routing call to combine the output of 20 functions and render as json to html.
My app.js function
var express = require('express');
var router = express.Router();
var path = require('path');
var app = express();
var todo = require('./modules/first');
var todo1 = require('./modules/second');
var connection = require('./connection');
connection.init();
app.get('/', function(req,res,next) {
Promise.all([todo.class1.getUsrCnt(),todo.class1.getTotlAmt(),todo.class1.getTotlOrdrCnt(),todo.class1.getTotlCntRcds(),todo.class1.getTotlScsRcds(),todo.class1.getTotlFailRcds(),todo.class1.getTotlAmtRcds()])
.then(function(allData) {
res.addHeader("Access-Control-Allow-Origin", "http://hostname:8183/");
res.json({ message3: allData });
});
res.send(send response to html);
})
app.get('/second', function(req,res,next) {
Promise.all([todo1.class2.getUsr........])
.then(function(allData) {
res.addHeader("Access-Control-Allow-Origin", "http://hostname:8183/");
res.json({ message3: allData });
});
res.send(send response to html);
})
var server = app.listen(8183, function(){
console.log('Server listening on port '+ server.address().port)
});
My todo.js is
var connection = require('../connection');
var data = {},obj={};
var d = new Date();
var month = d.getMonth() + 1;
var year = d.getFullYear();
obj.getUsrCnt = function getUsrCnt(callback) {
connection.acquire(function(err, con) {
con.query(query1, function(err, result) {
con.release();
data.usrs_cnt = result[0].some;
})
});
}
obj.getTotlAmt = function getTotlAmt(callback) {
connection.acquire(function(err, con) {
con.query(query2, function(err, result) {
con.release();
data.total_amt = result[0].some1;
})
});
}
obj.getTotlOrdrCnt = function getTotlOrdrCnt(callback) {
connection.acquire(function(err, con) {
con.query(query3, function(err, result) {
con.release();
data.total_orders = result[0].some2;
})
});
}
.
.
. functions go on
exports.class1 = obj;
Getting undefined in the promise all and unable to render to the html file.
Not sure about the code you wrote, but as I understand you want to call all the functions, get all the results and return back to the user?
so you can use many libraries that waits for several calls for example, promise based:
Promise.all([todo.getUsrCnt('dontcare'), todo.getTotlAmt('dontcate')])
.then(function(allData) {
// All data available here in the order it was called.
});
as for your updated code, you are not returning the data as promises, you assigning it to the local variable.
this is how your methods should look:
obj.getUsrCnt = function getUsrCnt(callback) {
var promise = new Promise(function(resolve, reject) {
connection.acquire(function(err, con) {
if(err) {
return reject(err);
}
con.query(query1, function(err, result) {
con.release();
resolve(result[0].some);
})
});
});
return promise;
}
as you can see here, I am creating a new promise and returning it in the main function.
Inside the new promise I have 2 methods: "resolve", "reject"
one is for the data and one is for errors.
so when you use the promise like this:
returnedPromise.then(function(data) {
//this data is what we got from resolve
}).catch(function(err) {
//this err is what we got from reject
});
you can see that a promise can or resolved or rejected,
do this to all the methods, and then you start seeing data

I am having issues with exporting in node

I am trying to make an api endpoint for data coming from dynamoDB. I believe that I have everything connected but when I run postman to check the api (api/db) it doesn't recognize the functions from the db.js in the db.js (for routes). I have run a test on api/test and am getting the information back. Here is the code from both files:
1. This scans the database and I'm trying to export it to another file.
var AWS = require('aws-sdk');
var params = {
TableName : "iotbuttonsn",
//KeyConditionExpression: "serialNumber =:serialNumber",
//ExpressionAttributeValues: {
// ":serialNumber":"*"
//},
ScanIndexForward: false,
Limit: 3,
Select: 'ALL_ATTRIBUTES'
};
AWS.config.update({
region: "us-east-1",
endpoint: "https://dynamodb.us-east-1.amazonaws.com"
});
var docClient = new AWS.DynamoDB.DocumentClient();
var getDatabase = (function(){
return {
scanDB: function(){
docClient.scan(params, onScan);
var onScan = function(err, data){
if (err) {
console.log(err.message);
} else {
console.log('scan success');
len = data.Items.length;
for (n=0; n<len; n++) {
clickTypes[n] = data.Items[n].payload.clickType;
serialNums[n] = data.Items[n].serialNumber;
}
}
};
},
clickTypes: [],
serialNums: []
};
})();
module.exports = getDatabase;
2. This is where I'm trying to input but db.scanDB() isn't working:
var router = require('express').Router();
var db = require('../routes/db.js');
router.get('/', function(req, res){
db.scanDB();
buttons =
[
iot_buttonOne = {
serialNum: db.serialNum[0],
clickType: db.clickTypes[0]
},
iot_buttonTwo = {
serialNum: db.serialNum[1],
clickType: db.clickTypes[1]
}
]
.then(
function scanSuccess(data){
res.json(data);
},
function scanError(err){
res.send(500, err.message);
}
);
});
module.exports = router;
Change your db.scan() function to properly return an asynchronous result:
// db.js
module.exports = {
scanDB: function(cb){
docClient.scan(params, function(err, data) {
var clickTypes = [], serialNums = [];
if (err) {
console.log(err.message);
cb(err);
} else {
console.log('scan success');
len = data.Items.length;
for (n=0; n<len; n++) {
clickTypes[n] = data.Items[n].payload.clickType;
serialNums[n] = data.Items[n].serialNumber;
}
cb(null, {clickTypes, serialNums});
}
});
}
};
Then, when you use it:
var db = require('../routes/db.js');
db.scanDB(function(err, data) {
if (!err) {
// data.clickTypes
// data.serialNums
} else {
// process error
}
});
It really does not good to put the scanDB result on the DB object the way you were doing because there was no way for the caller to know when the asynchronous operation was done. So, since you have to provide some notification for the caller when the async operation is done (either via callback or promise), you may as well just pass the results there too.
Also, the .then() handler in your router.get(...) handler does not belong there. I don't know why it's there at all as there are no promises involved in the code you show. Perhaps a cut/paste error when creating the question?
Note, I removed the IIFE from your getDatabase() definition since there was no benefit to it other than a little more complicated code.

unit testting using sinon+mockery+chai in node.js

I am very new to unit testing, so please guide me through the following: I am trying to unit test the following function...
helpers.js
function helpers() {
}
helpers.prototype.Amount = function(callback){
var Amount = 0;
app.models.xxx.find({}, function(err, res) {
if(err){
} else {
for(var i=0; i < res.length; i++){
Amount = Amount + res[i].hhhh;
}
return callback(null,Amount);
}
});
}
module.exports.helpers = helpers;
helpers-test.js
describe('helper', function(){
var AmountStub = sinon.stub(Helper.protoype,"getAmount");
it('should return the amount', function(done){
var helper = new Helper();
helper.getAmount(function(err, res){
assert.ifError(err);
});
done();
});
});
But i am receiving the following error:
/node_modules/sinon/lib/sinon/util/core.js:67
throw new TypeError("Should wrap property of object");
^
TypeError: Should wrap property of object
Please guide me through this. Also the way i am doing is right? Thanks in advance..
EDIT:
var Helper = require("../../server/helpers").helpers;
var helper = sinon.stub(
new Helper(),
"getAmount",
function (callback) { callback(1000); }
);
helper.getAmount(
function (value) {
expect(value).to.be.equal(1000);
done();
});
});
According to the sinon docs you need to pass an object itself, not its prototype.
var helper = sinon.stub(new Helper(), "getAmount");
In your case you would like to do stubbing inside the it test and provide the replacement for the function:
var helper = sinon.stub(
new Helper(),
"getAmount",
function (callback) { callback(dummyValue); }
);
helper.getAmount(
function (value) { done(); }
);

Issue with EventEmitter inheritance

I'm having a small issue, playing around with module patterns. I'm trying to attach an eventemitter to my library, but it doesn't seem to work and I get :
cmd.on('message',function(msg){
^
TypeError: undefined is not a function
My lib looks like :
var util = require('util');
var EventEmitter = require("events").EventEmitter;
var TestLib = function() {
var self = this;
function sendRandom(cb){
self.emit('message','whatever');
cb(null,0);
}
return {
init: function(cb) {
console.log('init');
cb(null);
},
run: function(params,cb){
console.log('running ',params);
sendRandom(function(err,res){
if(err){
cb(new Error(err));
}else{
cb(null,res);
}
});
},
close: function(cb) {}
};
};
util.inherits(TestLib, EventEmitter);
module.exports = TestLib;
And I call it as such :
var cmd = require(__dirname+'/bin/testlib.js')();
cmd.on('message',function(msg){
log(msg);
});
cmd.init(function(err){
if(err){
log(err);
}else{
cmd.run(line,function(err,res){
if(err){
log(err);
}else{
log(res);
}
});
}
});
I'm sure I'm overlooking something simple, but what?
see whether the example below helps you.
testLib.js
var EventEmitter = require('events').EventEmitter;
var util = require('util');
function TestLib(ms) {
var self = this;
EventEmitter.call(this);
this.random = function() {
//emitting 'random' event randomly
var ms = Math.random() * 100000 % 3000;
console.log('emitting random event in ' + ms + ' milliseconds');
setTimeout(function() {
self.emit('random', ms);
self.random();
}, ms);
return self;
}
}
util.inherits(TestLib, EventEmitter);
module.exports = TestLib;
test.js
var TestLib = require('./testLib');
new TestLib()
.random()
.on('random', function(ms) {
console.log('random event emitted after ' + ms + ' milliseconds');
});
to run it, execute node test.js

making event in module.exports functions

I'm trying to make a module with an even that I could call from the index file (after a require).
My code includes var events = require("events"); and I've wrote only the tricky part here.
index.js:
var reqw = require('./module.js');
reqw.on('data', function(d) {
console.log(d);
});
module.js:
module.exports = {
listaccts: function() {
events.EventEmitter.call(this);
}
}
util.inherits(exports.listaccts, events.EventEmitter);
exports.listaccts.prototype.listme = function() {
thisList = this;
var req = https.request(requestOptions, function(res) {
res.on('data', function(chuck) {
store = chuck;
});
res.on('end', function(d) {
thisList.emit("data", store.toString());
});
});
}
Searched the whole we and yet to find a proper answer..
Modified your code slightly :
module.js
function listaccts(){
}
util.inherits(listaccts, EventEmitter);
listaccts.prototype.listMe = function(){
var self = this;
var store = [];
console.log('here');
var req = https.request(requestOptions, function(res) {
res.on('data', function(chuck) {
console.log('data');
store.push(chuck);
});
res.on('end', function() {
console.log('end');
self.emit("data", store);
});
});
req.end();
};
module.exports = listaccts;
index.js
var reqw = require('./module');
var obj = new reqw();
obj.listMe();
obj.on('data', function(err, data) {
console.log(err);
});
req.end is important, I have forgot to include and got a never-ending cycle.
Created instance for binding this, so no need for EventEmitter.call.
Maybe you want to the listMe function to inside your constructor.
Hope this help.

Resources