can somebody help me to update some multiple object in
loopback but i don't have any idea on how to do it..
this is what i tried...
Bond.ParseBondQoutesheet = (data, cb) => { //eslint-disable-line
//// now update multiple
for (let i = 0; i <= data.length; i = +i) {
const filter = {
where: { id: data[i].id },
};
Bond.findOne(filter, (err, newdata) => {
if (!err) {
newdata.updateAttributes(data[i], function (err, updated) {
if (!err) {
if (data.length === i) {
console.log('updated success')
cb(null, updated);
}
} else {
console.log('err')
console.log(err)
cb(err, null);
}
})
} else {
cb(err, null);
}
});
}
};
is this correct?
You can run that but because of JavaScript's async nature it will behave unexpectedly
what you can do in order to solve this would be to loop it using recursive method like this
Bond.ParseBondQoutesheet = (data, cb) => { //eslint-disable-line
//// now update multiple
let data = data;
updateAllSync(0);
function updateAllSync(i) {
if (i < data.length) {
const filter = {
where: { id: data[i].id },
};
Bond.findOne(filter, (err, newdata) => {
if (!err) {
newdata.updateAttributes(data[i], function (err, updated) {
if (!err) {
if (data.length === i) {
console.log('updated success')
updateAllSync(i+1);
}
} else {
console.log('err')
console.log(err)
cb(err, null);
}
})
} else {
cb(err, null);
}
});
}else{
cb(null,i); // finished updating all docs sync
}
}
};
Related
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');
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.
I am trying to call method get_radar_life_cycle from app.get("/api/radar_cloning and it throws the error shown below,
error is coming from line return done(null,documents) how do I return documents back to my API call?
METHODS:-
let get_cloned_radars = function(documents, done) {
let complete_radar_list=[]
for (let i = 0; i < documents.length; i++) {
complete_radar_list.push(documents[i]['orgRadar']);
for (let j = 0; j < documents[i]['clonedRadarsdetailslist'].length; j++) {
complete_radar_list.push(documents[i]['clonedRadarsdetailslist'][j]['clonedRadar']);
}
}
data = complete_radar_list
return done(null, data)
}
let get_radar_life_cycle = function(data,done) {
console.log("data after get_radar_life_cycle")
console.log(data)
Radar_life_cycle.find({orgRadar: {$in:data}})
.then(documents => {
console.log(documents) --> shows correct data
});
return done(null,documents) --> Error is coming from this line
};
API call:
app.get("/api/radar_cloning", (req, res, next) => {
Radar_cloning.find({orgRadar: {$in:req.query.params.split(',')}})
.then(documents => {
get_cloned_radars(documents, function(err,data) {
if (err) {
res.json(err);
if (data!=null){
console.log(data)
}//end for data
}//end of (Err)
});//get_cloned_radars
get_radar_life_cycle(data, function(err,radar_life_cycle_data) {
if (err) {
res.json(err);
console.log(radar_life_cycle_data)
}//end for radar_life_cycle_data
}//end of (Err)
});//end of get_radar_life_cycle
});
});
ERROR:-
(node:10065) UnhandledPromiseRejectionWarning: ReferenceError: documents is not defined
You are trying to access documents outside of its scope, the scope being everything between the { and }. So you cannot access it below the .then(() => {}) scope.
Luckily you are are providing a callback function called done(err, radar_life_cycle_data), which you can use anywhere in the scope of the get_radar_life_cycle(documents, done) function. Even the scopes inside of its scope. When you are calling the done function, what you are basically doing is calling this function (well it has some syntax errors, so I cleaned it up)
function(err,radar_life_cycle_data) {
if (err) {
res.json(err);
console.log(radar_life_cycle_data)
}
}//end for radar_life_cycle_data
which then gets executed
So the solution:
Move your done in your .then(() => {}) scope like this:
let get_radar_life_cycle = function(data,done) {
console.log("data after get_radar_life_cycle")
console.log(data)
Radar_life_cycle.find({orgRadar: {$in:data}})
.then(documents => {
console.log(documents) // --> shows correct data
done(null,documents) // --> No error coming from this line
});
};
Same goes for the data it is not in the scope of the get_cloned_radars
app.get("/api/radar_cloning", (req, res, next) => {
Radar_cloning.find({orgRadar: {$in:req.query.params.split(',')}})
.then(documents => {
get_cloned_radars(documents, function(err,data) {
if (err) {
res.json(err);
if (data!=null) {
console.log(data)
get_radar_life_cycle(data, function(err,radar_life_cycle_data) {
if (err) {
res.json(err);
console.log(radar_life_cycle_data)
} //end of (Err)
}); //end of get_radar_life_cycle
} //end for data
} //end of (Err)
}); //get_cloned_radars
});
But since your code is unreadable, here is a cleaned up version:
app.get("/api/radar_cloning", (req, res, next) => {
const radar_life_cycle_cb = function (err, data) {
if (err) {
res.json(err);
return;
}
console.log(data);
}
const cloned_radar_cb = function (err, data) {
if (err) {
res.json(err);
return;
}
if (data != null) {
get_radar_life_cycle(data, radar_life_cycle_cb);
}
};
Radar_cloning.find({orgRadar: {$in:req.query.params.split(',')}})
.then(documents => get_cloned_radars(documents, cloned_radar_cb));
}
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'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.