I am working on nodejs and i am using "Express js" framework, I am working on Controller and i am trying to get data from "two model functions" but i am getting message "anonymous", How can i get data from multiple "model functions", Here is my code,
This is my homeController
homeController.index = function (req, res, next) {
// fetching data into 'data variable' from FetchRecords model
homeModel.FetchRecords(function (err, data) {
if (err) {
req.flash('error', 'There was no records.');
} else {
res.render('home/index', { data: data });
}
});
homeModel.getAverage(function (average) {
console.log(average);
// res.render('home/index',{data:average});
});
};
This is my homeMOdel
homeModel.FetchRecords = function (data) {
sql.query('SELECT * FROM rating', function (err, res) {
if (err) {
return data(err, null);
} else {
return data(null, res);
}
});
};
homeModel.getAverage = function (average) {
console.log(average);
sql.query('SELECT avg(value) FROM rating', function (err, res) {
if (err) {
return average(err, null);
} else {
return average(null, res);
}
});
};
Inside homeModel just create 1 function instead of 2 separate. You can combine both MySQL queries into one like this.
const FetchRecordsAndAverage = function (data) {
sql.query('SELECT * FROM rating; SELECT avg(value) FROM rating', function (err, res) {
if (err) {
return data(err, null);
} else {
return data(null, res);
}
});
};
module.exports = {
FetchRecordsAndAverage
}
With this you will get combined data of both queries as arrays inside array.
Result of queries can be accessed as data[0] & data[1].
You should export the function from the home model:
const FetchRecords = function (data) {
sql.query('SELECT * FROM rating', function (err, res) {
if (err) {
return data(err, null);
} else {
return data(null, res);
}
});
};
const getAverage = function (average) {
console.log(average);
sql.query('SELECT avg(value) FROM rating', function (err, res) {
if (err) {
return average(err, null);
} else {
return average(null, res);
}
});
};
module.exports = {
FetchRecords,
getAverage
}
And retrieve them in your application by calling:
const { FetchRecords, getAverage } = require('./path/to/home_model');
Related
I am using node-async-loop for asyncronous programming
var array = ['item0', 'item1', 'item2'];
asyncLoop(array, function (item, next)
{
do.some.action(item, function (err)
{
if (err)
{
next(err);
return;
}
next();
});
}, function (err)
{
if (err)
{
console.error('Error: ' + err.message);
return;
}
console.log('Finished!');
});
Like this I am using three async loops one under one.
I want to send the response only after the third inner loop ends. How can I do so?.
Here is the link for node-async-loop (https://www.npmjs.com/package/node-async-loop)
here is my code which i writing but whnever i want to response when the last loop completes it say can set header after send to cliend.
also in console log i am getting data every time when data coming from query.
const id = req.params.id;
finalData = [];
tb_user.findOne({ where: { id: id } }).then((userRiverSys, err) => {
if (userRiverSys) {
// console.log(userRiverSys.regionJson)
asyncLoop(userRiverSys.regionJson, function (item, next) {
// console.log("item", item);
tb_riverSystems.findAll(
{
where: { regionId: item.id }
}).then((findriverSys, err) => {
if (err) {
next(err);
return;
}
// console.log("findriverSys", findriverSys);
if (findriverSys) {
asyncLoop(findriverSys, function (item1, next1) {
if (err) {
next(err);
return;
}
// console.log("item1", item1.dataValues);
tb_facilities.findAll(
{
where: { riverSystemId: item1.dataValues.id }
}).then((findFacilities) => {
if (findFacilities) {
// console.log("findFacilities", findFacilities[0].dataValues.name);
asyncLoop(findFacilities, function (item2, next2) {
if (err) {
next(err);
return;
}
tb_userAccess.findAll(
{
where: { facilityId: item2.dataValues.id }
}).then((userAccessFacilities, err) => {
// console.log("userAccessFacilities", userAccessFacilities[0].dataValues);
// var i = 0;
asyncLoop(userAccessFacilities, function (item3, next3) {
finalData.push({
UserId: item3.userid,
facilityId: item3.facilityId,
})
next3();
},
function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
// i++;
// console.log('Finished!!!!');
// if (userAccessFacilities.length === i) {
// console.log("finalData", i);
// // res.json({"status":"true", "message":"update OrgChallenge"})
// }
})
return res.json({"status":"true", "message":"update OrgChallenge"})
// console.log("finalData", finalData);
})
next2();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!!!');
});
}
});
next1();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!!');
});
}
});
next();
}, function (err) {
if (err) {
console.error('Error: ' + err.message);
return;
}
console.log('Finished!');
});
} else {
console.log("err3", err)
}
})
If you promisify your asynchronous action (so it returns a promise), then you can just use a regular for loop and async/await and there is no need for a 3rd party library to sequence your asynchronous loop. This is modern Javascript:
const { promisify } = require('util');
do.some.actionP = promisify(do.some.action);
async function someFunction() {
const array = ['item0', 'item1', 'item2'];
for (let item of array) {
let result = await do.some.actionP(item);
// do something with result here
}
return someFinalResult;
}
someFunction().then(result => {
console.log(result);
}).catch(err => {
console.log(err);
});
FYI, in real code, many (or even most) asynchronous operations now offer promisified versions of their API already so usually you don't even need to do the promisify step any more. For example, pretty much all databases already offer a promise interface that you can just use directly.
const loop = async (arr, results = []) => {
const item = arr.shift()
if (!item) {
console.log("DONE");
return results;
}
// as async function
await new Promise(resolve => {
resolve(results.push(`asynced-${item}`))
})
return loop(arr, results);
}
(async () => {
const result = await loop(["item0", "item1", "item2"])
console.log(result);
})();
I'd be happy if I can help you.
but this script uses a recursive function instead of node-async-loop.
so this might not be suitable for you.
calling id from mongodb with callback function
var GetID = function (nameval, callback) {
console.log(nameval);
console.log("munesh hello");
GenerateID.find({ "id_name": nameval }, {
"id_code": 1,
"id_value": 1, "_id": 0
}, function (err, genvalue) {
if (err) {
console.log('hello');
}
else {
if (genvalue === null) {
callback(err, false);
}
else {
callback(err, true);
}
}
console.log(genvalue);
});
};
and calling above method so we need
so we need id from GenerateID.GetID and do our own work.
var region_id = GenerateID.GetID(name, function (error, result) {
if (error) {
console.log("getting any error");
} else {
console.log(region_id);
if (!result) {
console.log('data is not coming');
} else {
console.log('data is coming');
}
}
});
You have a number of issues. In the first piece of code, you need to pass the actual value when calling the callback.
In the second, you need to set region_id = result.
Ideally you would do this using promises as demonstrated below.
var GetID = function(nameval){
return new Promise((resolve,reject) => {
console.log(nameval);
console.log("munesh hello");
GenerateId.find({ "id_name" : nameval },{"id_code":1 , "id_value":1, "_id":0},
function( err , genvalue ) {
console.log(genvalue);
if (err) {
console.log('hello');
return reject()
}
if (genvalue == null) { return resolve(false); }
return resolve(genValue);
});
});
}
var GetIDPromise = GenerateId.GetID(name);
GetIDPromise.then(
genValue => {
if ( genValue == false ){
console.log('data is not coming');
// handle region id not being available. Perhaps return and show an error
}else{
var region_id = genValue;
// continue execution and use region id.
}
},
error => {
console.log("getting any error");
}
)
I have a route and I want to execute different functions for each service
var planning = require('../tms/planning.js');
router.get('/tms/api/:service', isAuthenticated, function(req, res, next) {
if (req.params.service == 'depot_planning') {
planning.depots(req, function(results) {
res.send({
'result': {
'data': results
}
});
});
} else if (req.params.service == 'affiche_planning') {
planning.AffichePlanning(req, function(result) {
res.send({
'result': {
'data': result
}
});
});
}
});
the functions that i call
var t = require('./DB2connexion');
var database = t.database;
var depots = function(req, callback) {
statement = 'SELECT distinct plptrs FROM MTFPLAP';
database.execute(statement);
database.on('execute', function(error, results, next) {
if (error) {
console.log(error);
} else {
callback(results, next);
}
});
}
var AffichePlanning = function(req, callback) {
statement = 'SELECT otnump,otquai,OTHCR,Otnbps from MTFodtp where OTDCR=\'' + req.query.datePlanning +
'\' and ottype=\'CDE\' and OTLP=\'NOR\' order by otquai asc,OTHCR asc';
console.log(statement);
database.execute(statement);
database.on('execute', function(error, results) {
if (error) {
console.log(error);
} else {
callback(results, next);
}
});
}
module.exports.depots = depots;
module.exports.AffichePlanning = AffichePlanning;
When i execute my code I have the same results returned for the two routes, how can i do to have the good result for each call?
I'm writing a policy checkSession which basically destroy session after some time.
checkSession.js (policies/checksession.js)
var moment = require('moment');
function checkLastActivity(req) {
if (!req.session.lastActivity) {
return false; // no session.
} else {
return true;
}
}
function setActivity(req) {
req.session.lastActivity = moment(new Date()).format();
return true;
}
function updateActivity(req, res, updated) {
req.session.lastActivity = moment(new Date()).format();
updated(null, {
isdestroted: 0
});
}
function checkIdleTime(req, idleTime) {
try {
var lastActivityTime = moment(req.session.lastActivity).format();
var currentActivityTime = moment(new Date()).format();
timeIdle = moment.utc(moment(currentActivityTime).diff(moment(lastActivityTime))).format("HH:mm:ss");
minutestimeIdle = moment.duration(timeIdle).asMinutes().toFixed(2);
idleTime(null, minutestimeIdle);
} catch (e) {
idleTime(e, null);
}
}
function destroyActivity(req, res, destroyed) {
try {
req.session.destroy();
sails.log.info("***********************session is expired for user *****************");
destroyed(null, {
isdestroted: 1,
redirectCode: 200,
redirectView: '/login/'
});
} catch(e) {
destroyed(e, null);
}
}
module.exports = function isSession(req, res, next) {
cleanParamsService.cleanPrm(req);
async.waterfall([
function(callback) {
callback(null, checkLastActivity(req));
},
function(isLastActivity, callback) {
if (isLastActivity) {
checkIdleTime(req, function(err, timeIdle) {
if (minutestimeIdle > sails.config.session_timeout) { /*if user is being idle*/
destroyActivity(req, res, function(err, destroyed) {
sails.log.warn('User was idle since' + minutestimeIdle + ', sessions are destroyed');
callback(null, destroyed);
})
} else {
updateActivity(req, res, function(err, updated) {
callback(null, updated);
});
}
})
} else {
updateActivity(req, res, function(err, updated) {
callback(null, updated);
});
}
}
], function(err, result) {
if (result) {
if (result.isdestroted == 0) {
return next();
} else {
return res.redirect(result.redirectCode, result.redirectView);
}
} else {
sails.log.error('err:', err);
return res.badRequest();
}
});
};
now if i change it to
var moment = require('moment');
function checkLastActivity(req) {
if (!req.session.lastActivity) {
return false; // no session.
} else {
return true;
}
}
function setActivity(req) {
req.session.lastActivity = moment(new Date()).format();
return true;
}
function updateActivity(req, res, updated) {
req.session.lastActivity = moment(new Date()).format();
updated(null, {
isdestroted: 0
});
}
function checkIdleTime(req, idleTime) {
try {
var lastActivityTime = moment(req.session.lastActivity).format();
var currentActivityTime = moment(new Date()).format();
timeIdle = moment.utc(moment(currentActivityTime).diff(moment(lastActivityTime))).format("HH:mm:ss");
minutestimeIdle = moment.duration(timeIdle).asMinutes().toFixed(2);
idleTime(null, minutestimeIdle);
} catch (e) {
idleTime(e, null);
}
}
function destroyActivity(req, res, destroyed) {
try {
req.session.destroy();
sails.log.info("***********************session is expired for user *****************");
destroyed(null, {
isdestroted: 1,
redirectCode: 200,
redirectView: '/login/'
});
} catch (e) {
destroyed(e, null);
}
}
module.exports = function isSession(req, res, next) {
cleanParamsService.cleanPrm(req);
async.waterfall([
function(callback) {
callback(null, checkLastActivity(req));
},
function(isLastActivity, callback) {
if (isLastActivity) {
checkIdleTime(req, function(err, timeIdle) {
if (minutestimeIdle > sails.config.session_timeout) { /*if user is being idle*/
destroyActivity(req, res, function(err, destroyed) {
sails.log.warn('User was idle since' + minutestimeIdle + ', sessions are destroyed');
callback(null, destroyed);
})
} else {
updateActivity(req, res, function(err, updated) {
callback(null, updated);
});
}
})
} else {
updateActivity(req, res, function(err, updated) {
callback(null, updated);
});
}
},
function(resp, callback) {
if (resp.isdestroted == 0) {
req.fresh;
req.session.isdestroted = false;
callback(null, resp);
} else {
req.fresh;
req.session.isdestroted = true;
callback(null, resp);
}
}
], function(err, result) {
if (result) {
if (result.isdestroted == 0) {
return next();
} else {
return res.redirect(result.redirectCode, result.redirectView);
}
} else {
sails.log.error('err:', err);
return res.badRequest();
}
});
};
The application trigger error where i'm setting req.session.isdestroted = true/false and the error is
warn: User was idle since0.38, sessions are destroyed
debug: Lowering sails...
C:\Users\Vbase002\Desktop\CC\Website\api\policies\checkSession.js:83
req.session.isdestroted = true;
^
TypeError: Cannot set property 'isdestroted' of undefined
at C:\Users\Vbase002\Desktop\CC\Website\api\policies\checkSession.js:83:41
at fn (C:\Users\Vbase002\Desktop\CC\Website\node_modules\sails\node_modules\
async\lib\async.js:579:34)
at Immediate._onImmediate (C:\Users\Vbase002\Desktop\CC\Website\node_modules
\sails\node_modules\async\lib\async.js:495:34)
at processImmediate [as _immediateCallback] (timers.js:367:17)
i'm setting this session to show some message on login page to user, but i don't know why sails is behaving like this.
is there any way to handle this scenario and also please let me know the reason why this is happening.
Thanks
This is a behavior from express.
Session.destroy()
Destroys the session, removing req.session, will be re-generated next
request.
As your warn log indicates, req.session.destroy(); has been called before the error.
You could use req.session.regenerate() to have the expected behavior.
Session.regenerate()
To regenerate the session simply invoke the method, once complete a
new SID and Session instance will be initialized at req.session.
When I run collection.find() in MongoDB/Node/Express, I need to return value for my array like this but iam in callback hell;
foursquare.getVenues(params,function(error, venues) {
if (!error) {
var places = [];
venues.response.venues.forEach(function(e) {
places.push(
{
obj_id:e.id,
name:e.name,
distance:e.distance,
here_now:req.collection.findById(e.id) //count- i want need this value
}
);
});
res.send(places);
}
});
You can try to use Async https://github.com/caolan/async#each
var async = require('async');
...
foursquare.getVenues(params, function (error, venues) {
if (!error) {
throw err;
}
var places = [];
async.each(venues.response.venues, function (e, callback) {
db.collection.findById(e.id, function (err, res) {
places.push({
obj_id: e.id,
name: e.name,
distance: e.distance,
here_now: res
});
callback()
});
}, function (err) {
if (err) {
console.log('A file failed to process');
} else {
console.log('All files have been processed successfully');
res.send(places);
}
});
});
or Using async.map
var async = require('async');
var createArray = function (e, cb) {
db.collection.findById(e.id,function(err,res){
var obj = {
obj_id: e.id,
name: e.name,
distance: e.distance,
here_now: res
}
cb(null, obj);
});
}
async.map(venues.response.venues, createArray, function (err, places) {
if(err){
throw err;
}
console.log(places);
});