findOne not executed - node.js

I have the code below:
exports.getMyPets = function (req, res){
var email = req.body.email;
var result = [{}];
Owner.findOne({"email" : email }, "_id", function(err, owner){
if(err)
res.send(err);
console.log("Owner: " + owner._id + "\n");
Pet.find({"OwnerId": owner._id}, function(err, pet) {
if(err)
res.send(err)
var index = pet.length;
var empty = false;
if(index > 0)
empty = true;
try{
for (let x = 0; x < index; x += 1){
PetPicture.findOne({"petId" : pet[x]._id}, function (err, petPic){
console.log('pet ID: ' + pet[x]._id);
result[x] = {
name: pet[x].name,
breed: pet[x].breed,
description: pet[x].description,
imageType: petPic.imageType,
imageData: petPic.imageType
};
}); //end of petPicture.findOne
console.log('X : ' + pet[x]._id);
}// end of for loop
} catch (error){
console.log(error);
}
}
while(true){
if (result.length === index)
break;
}
if(!empty){
res.json(pet);
} else {
res.json(result);
}
}); // end of Pet,find
}); // end of petOwner.findOne
};
The block of PetPicture.findOne (the whole try catch block) does not get executed when I try to call it on endpoint. It does not log anything, not even an error on the catch part. What can I do to debug this?

Related

display 2 two table records in nodejs

I have tow MongoDB collection.
1) users
2) reviews.
at the first collection, I have stored username and id. and 2nd table I have stored user_id and comments and star rating.
I want to display on listing page users and his reviews.
I have written below code but it is not working.
var getTopSellers = function () {
var defer = Q.defer();
User.find({ isRegistered: true }).sort({ updatedAt: -1 }).limit(10).exec(function (err, sellers) {
if (!err) {
if (sellers && sellers.length > 0) {
for (var i = 0; i < sellers.length; i++) {
var sellerDetails = {};
var tempObj = {};
try {
tempObj.reviews = getreviews(sellers[i]._id);
sellerArr.push(tempObj);
} catch (e) {
// console.log("catch error:-", e);
}
}
out = U.getJson(C.SUCCESS_CODE, C.SUCCESS, sellerArr);
defer.resolve(out);
} else {
out = U.getJson(C.KNOWN_ERROR_CODE, 'No data found');
defer.reject(out);
}
} else {
console.log("Error:-", err);
out = U.getJson(C.ERROR_CODE, C.INETRNAL_SERVER_ERROR, b, err);
defer.reject(out);
}
})
return defer.promise;
};
var getreviews = function (user_id) {
var defer = Q.defer();
Review.find({ user_type: user_id }).sort({ updatedAt: -1 }).limit(10).exec(function (err, reviews) {
if (!err) {
if (reviews && reviews.length > 0) {
out = U.getJson(C.SUCCESS_CODE, C.SUCCESS, reviews);
defer.resolve(out);
} else {
out = U.getJson(C.KNOWN_ERROR_CODE, 'No data found');
defer.reject(out);
}
} else {
console.log("Error:-", err);
out = U.getJson(C.ERROR_CODE, C.INETRNAL_SERVER_ERROR, b, err);
defer.reject(out);
}
})
return defer.promise;
};
Please suggest

How can I use session token for repetitive calls of GEOTAB apis in node js wrapper?

I am using GEOTAB apis to sync vehicle data to my DB.In my software user can register and add geotab account to sync.for sync purpose i have used node js wrapper.With 3 minutes delay this process calls regularly.
I am getting the error "Global login limit exceeded"
var syncUsers = function () {
var i;
async.forEach(geotabUsers, function (geoUser, callback) {
//get index
i = geotabUsers.indexOf(geoUser);
if (apiInstanse[geotabUsers[i].userId] === undefined)
{
apiInstanse[geotabUsers[i].userId] = new API(geotabUsers[i].apiUsername, geotabUsers[i].apiPassword, geotabUsers[i].apiDatabase, js_lang.GEOTAB_SERVER);
}
//sync status data
syncStatusData(apiInstanse[geotabUsers[i].userId], i, userInfo[geotabUsers[i].userId].statusDataFromVersion, geotabUsers[i].userId, userInfo[geotabUsers[i].userId].currentCompany, geotabUsers[i].apiUsername, geotabUsers[i].apiPassword, geotabUsers[i].apiDatabase, userInfo[geotabUsers[i].userId].currentPressureUnit, userInfo[geotabUsers[i].userId].currentDateFormat, userInfo[geotabUsers[i].userId].currentTimeFormat, userInfo[geotabUsers[i].userId].currentTemperatureUnit);
//sync fault data
syncFaultData(apiInstanse[geotabUsers[i].userId], i, userInfo[geotabUsers[i].userId].faultDataFromVersion, geotabUsers[i].userId, userInfo[geotabUsers[i].userId].currentCompany, geotabUsers[i].apiUsername, geotabUsers[i].apiPassword, geotabUsers[i].apiDatabase,function(){
callback();
});
},function(err){
if(err)
{
console.log('done errro:',err);
}
console.log('sync done');
continueSync();
});
Function to sync status data:
var syncStatusData = function (api, i, fromVersion, userId, currentCompany, apiUsername, apiPassword, apiDatabase, currentPressureUnit, currentDateFormat, currentTimeFormat, currentTemperatureUnits)
{
try {
api.call(js_lang.GEOTAB_GETFEED_METHOD, {
typeName: js_lang.GEOTAB_STATUS_DATA,
resultsLimit: js_lang.GEOTAB_API_LIMIT,
fromVersion: fromVersion
}, function (err, data) {
if (err) {
console.log('api Call Error:', userId);
console.log('apiUsername:', apiUsername);
console.log('apiPassword:', apiPassword);
console.log('apiDatabase:', apiDatabase);
console.log('Error', err);
//apiInstanse[userId] = new API(apiUsername, apiPassword, apiDatabase, js_lang.GEOTAB_SERVER);
//throw err;
}
else {
var insertStatus = [];
var sql = "INSERT INTO " + js_lang.TABLE_STATUS_DATA + " (companyId,dateTime,deviceId ,diagnosticId,value,version,uniqueId,userId,unitOfMeasure ) VALUES ?";
//iterate data
if (data.data !== undefined)
{
for (var key in data.data) {
if (diagnosticList[data.data[key].diagnostic.id] === undefined)
{
continue;
}
var normalDate = FUNCTION_CLASS.getNormalDateFromUTC(data.data[key].dateTime);
//prepare data to insert
var insertRow = [
currentCompany,
normalDate,
data.data[key].device.id,
data.data[key].diagnostic.id,
data.data[key].data,
data.data[key].version,
data.data[key].id,
userId,
diagnosticList[data.data[key].diagnostic.id].unitOfMeasure
];
insertStatus.push(insertRow);
}
}
if (insertStatus.length > 0)
{
connection.query(sql, [insertStatus], function (err) {
if (err)
{
throw err;
}
// console.log('toversion:', data.toVersion);
console.log('insert:userId:', userId);
connection.query('UPDATE ' + js_lang.TABLE_USER + ' SET statusDataFromVersion = ? WHERE id = ?',
[data.toVersion, userId]);
});
}
else {
console.log('update user:', userId);
connection.query('UPDATE ' + js_lang.TABLE_USER + ' SET statusDataFromVersion = ? WHERE id = ?',
[data.toVersion, userId]);
}
}
if ((geotabUsers.length - 1) === i)
{
console.log('loop ended');
syncStatusDone = 1;
// continueSync();
}
});
}
catch (e) {
continueSync();
}
}
Function to sync Fault data:
var syncFaultData = function (api, i, fromVersion, userId, currentCompany, apiUsername, apiPassword, apiDatabase,callback)
{
try {
api.call(js_lang.GEOTAB_GETFEED_METHOD, {
typeName: js_lang.GEOTAB_FAULT_DATA,
resultsLimit: js_lang.GEOTAB_API_LIMIT,
fromVersion: fromVersion
}, function (err, data) {
if (err) {
console.log('api faultData Call Error:', userId);
console.log('apiUsername:', apiUsername);
console.log('apiPassword:', apiPassword);
console.log('apiDatabase:', apiDatabase);
console.log('Error', err);
//apiInstanse[userId] = new API(apiUsername, apiPassword, apiDatabase, js_lang.GEOTAB_SERVER);
//throw err;
}
else {
var insertStatus = [];
var sql = "INSERT INTO " + js_lang.TABLE_FAULT_DATA + " (amberWarningLamp,controllerId,count,dateTime,deviceId ,diagnosticId,dismissDateTime,dismissUser,failureModeId,faultLampState,faultState,flashCode,uniqueId,malfunctionLamp,protectWarningLamp,redStopLamp,version,companyId,userId,deleted) VALUES ?";
//iterate data
if (data.data !== undefined)
{
for (var key in data.data) {
if (diagnosticList[data.data[key].diagnostic.id] == undefined)
{
continue;
}
var normalDate = FUNCTION_CLASS.getNormalDateFromUTC(data.data[key].dateTime);
var thisDate = moment(new Date(data.data[key].dateTime)).tz(js_lang.TIMEZONE).format(js_lang.DATETIME_FORMAT);
var thisDayDate = moment(new Date(data.data[key].dateTime)).tz(js_lang.TIMEZONE).format(js_lang.DATE_FORMAT);
var controllerId = '';
if (data.data[key].controller !== undefined && data.data[key].controller.id !== undefined)
{
controllerId = data.data[key].controller.id;
}
else if (data.data[key].controller !== undefined)
{
controllerId = data.data[key].controller;
}
var faultcount = null;
if (data.data[key].count !== undefined)
{
faultcount = parseInt(data.data[key].count);
}
var dismissDateTime = '';
if (data.data[key].dismissDateTime !== undefined)
{
dismissDateTime = moment(new Date(data.data[key].dismissDateTime)).tz(js_lang.TIMEZONE).format(js_lang.DATETIME_FORMAT);
}
var dismissUser = '';
if (data.data[key].dismissUser !== undefined)
{
dismissUser = data.data[key].dismissUser;
}
var failureModeId = '';
if (data.data[key].failureModeId !== undefined && data.data[key].failureModeId.id !== undefined)
{
failureModeId = data.data[key].failureModeId.id;
}
var faultLampState = '';
if (data.data[key].faultLampState !== undefined)
{
faultLampState = data.data[key].faultLampState;
}
var faultState = data.data[key].faultState;
var flashCode = '';
if (data.data[key].flashCode !== undefined)
{
flashCode = data.data[key].flashCode;
}
var malfunctionLamp = data.data[key].malfunctionLamp;
var protectWarningLamp = data.data[key].protectWarningLamp;
var redStopLamp = data.data[key].redStopLamp;
var version = '';
if (data.data[key].version !== undefined)
{
version = data.data[key].version;
}
//prepare data to insert
var insertRow = [
data.data[key].amberWarningLamp,
controllerId,
faultcount,
normalDate,
data.data[key].device.id,
data.data[key].diagnostic.id,
dismissDateTime,
dismissUser,
failureModeId,
faultLampState,
faultState,
flashCode,
data.data[key].id,
malfunctionLamp,
protectWarningLamp,
redStopLamp,
version,
currentCompany,
userId,
0
];
insertStatus.push(insertRow);
}
}
// console.log(insertStatus);
if (insertStatus.length > 0)
{
connection.query(sql, [insertStatus], function (err) {
if (err)
{
throw err;
}
// console.log('toversion:', data.toVersion);
console.log('insert faultData:userId:', userId);
connection.query('UPDATE ' + js_lang.TABLE_USER + ' SET faultDataFromVersion = ? WHERE id = ?',
[data.toVersion, userId]);
callback();
});
}
else {
console.log('update faultData user:', userId);
//test code
//sendEmail(['ankkubosstest#gmail.com','webdeveloper#gmail.com'], 'emailSubject', 'emailText', '<div>html code<div>');
connection.query('UPDATE ' + js_lang.TABLE_USER + ' SET faultDataFromVersion = ? WHERE id = ?',
[data.toVersion, userId]);
callback();
}
}
if ((geotabUsers.length - 1) === i)
{
console.log('loop ended');
syncFaultDone = 1;
}
});
}
catch (e) {
continueSync();
}
}

Maximum open cursors exceeded in Node.js

I'm working on some code to process a csv in Node.js and store it in an Oracle database. So far, things are going well, but with large amounts of rows in the csv, I get "ORA-01000: maximum open cursors exceeded." I am connecting to Oracle once at the beginning of the script. For each record in the csv, I am preforming multiple SELECTs, INSERTs, and DELETEs and then moving on to the next entry to process all using the same connection. At the end, I close the connection. One thought I had was to get a new connection each time from a pool, but I read other posts saying I should use one connection. Perhaps I need to set a special setting to handle all these queries on one connection?
The script is kind of long, so I will post the important parts...I can post more if needed. Using Q, csvtojson, and oracledb.
...
var conn = null;
function connect() {
var deferred = Q.defer();
oracledb.outFormat = oracledb.OBJECT;
oracledb.getConnection(
{
user : 'foo',
password : 'bar',
connectString : 'foo.bar/bar',
},
function(err, c) {
if(err) deferred.reject(new Error(err));
// set global connection
conn = c;
deferred.resolve();
}
);
return deferred.promise;
}
function closeConnection(conn) {
var deferred = Q.defer();
conn.release(function(err){
if(err) deferred.reject(err);
else return deferred.resolve();
});
return deferred.promise;
}
/* Process All Data, Promise Loop */
function process(data) {
return processEntry(data.shift()).then(function(){
console.log('Finished processing entry.');
return data.length > 0 ? process(data) : true;
});
}
/* Process an Entry */
function processEntry(entry) {
var deferred = Q.defer();
var data = {};
entryExists(entry)
.then(function(result) {
if(result) return entryLogicError(null, 'Entry exists. Skipping.');
else return getUserFromReleaseCode(entry);
})
.then(function(result) {
if(typeof result != 'undefined' && result.length > 0) {
data.user = result[0];
return getPanelCode(entry);
}
else return entryLogicError(entry, 'No valid release code.');
})
.then(function(result){
if(typeof result != 'undefined' && result.length > 0) {
return createHeader(result[0].foo, result[0].bar);
}
else return entryLogicError(entry, 'No valid panel code.');
})
... More of the same kind of statements processing the entry ...
.then(function() {
return logEntry(entry);
})
.catch(function(error) { console.log("DATA ERROR: " + error) })
.done(function(){
deferred.resolve();
});
return deferred.promise;
}
function entryLogicError() {
// logs entry to be corrected, return a rejected promise to go to the next entry
}
/* Check if record has been processed */
function entryExists(entry) {
var deferred = Q.defer();
var foo = entry[ENTRY_CONST.FOO];
var bar = entry[ENTRY_CONST.BAR];
conn.execute(
'SELECT * FROM TBL_FOO ' +
'WHERE FOO = :foo AND ' +
'BAR = :bar',
[foo, bar],
function(err, result) {
if(err) deferred.reject(err);
else {
deferred.resolve(result.rows.length > 0);
}
});
return deferred.promise;
}
/* Get User from Release Code */
function getUserFromReleaseCode(entry) {
var deferred = Q.defer();
var foo = entry[ENTRY_CONST.FOO];
conn.execute(
'SELECT * FROM TBL_BAR ' +
'WHERE FOO = :foo',
[foo],
function(err, result) {
if(err) deferred.reject(err);
else {
deferred.resolve(result.rows);
}
});
return deferred.promise;
}
/* Create Header */
function createHeader(foo, bar) {
var deferred = Q.defer();
conn.execute(
'BEGIN INSERT INTO TBL_DR_FOO VALUES (NULL,:foo, :bar,' +
'1,NULL,1,NULL,NULL,NULL,NULL) RETURNING DR_FOO_ID INTO :DR_FOO_ID; COMMIT; END;',
{ foo: foo,
bar: bar,
DR_FOO_ID: { dir: oracledb.BIND_OUT, type: oracledb.NUMBER }
},
function(err, result) {
if(err) deferred.reject(err);
else deferred.resolve(result.outBinds);
});
return deferred.promise;
}
function cleanHistory() {
// statement that deletes records from a certain date using conn.execute(..)
}
/* Main */
connect().then(function(){
var converter = new Converter({ noheader: false });
converter.on('end_parsed', function(data) {
process(data).then(function(){
return cleanHistory();
})
.then(function(){
return closeConnection();
}).done();
});
fs.createReadStream(batch).pipe(converter);
}, function(err){
return console.error(err);
});

Getting Response of a function defined in another file in node.js

I have a socket function defined as
var funcs = require('./funcs');
socket.on(EVENT_ACCEPT_ORDER, function(data, callback)
{
data = JSON.parse(data);
var bookingId = data.bookingId;
var userId = data.userId;
console.log("Accepting booking...." + bookingId);
var query = "UPDATE bookings SET bookingStatus = " + BOOKING_STATUS_ACCEPTED + " WHERE id = " + bookingId + " AND bookingStatus = " + BOOKING_STATUS_IN_QUEUE;
con.query(query, function(err, rows,fields)
{
if(err)
{
console.log("mysql query error");
}
else
{
if(rows.changedRows > 0)
{
var indexOfUser = usersList.indexOf(userId);
if(indexOfUser > -1)
{
userSockets[indexOfUser].emit(EVENT_USER_ORDER_ACCEPTED);
}
callback({"message": "Success","error":false, "booking": funcs.getBooking(con, bookingId)});
}
else
callback({"message": "Success","error":true});
}
});
});
Funcs is defined as
module.exports = {
"getBooking": function (con, bookingId)
{
var query = "SELECT * FROM bookings WHERE id = " + bookingId + " LIMIT 1";
con.query(query, function(err, rows,fields)
{
if(err)
{
console.log("mysql query error");
}
else if (rows.length == 1)
{
var booking = rows[0];
var userId = rows[0]['userId'];
var query = "SELECT id, name, phone, imagePath FROM users WHERE id = " + userId + " LIMIT 1";
con.query(query, function(err, rows,fields)
{
if(err)
{
console.log("mysql query error");
}
else if (rows.length == 1)
{
booking['user'] = rows[0];
return booking;
}
});
}
});
}
}
Everything is running fine except
callback({"message": "Success","error":false, "booking": funcs.getBooking(con, bookingId)});
in this function instead of booking, i am only getting
{"error":false,"message":"Success"}
Why am i not getting the booking function result?
You are not getting the result, because the result of the callback function in con.query is not returned to the caller of getBooking. It is the asynchronous pattern, which you are not processing correctly.
The way it is supposed to work is that the getBooking gets an extra argument: a function to be called when data are available (in an internal asynchronous call to con.query). Such a function is then provided by the caller and in this function you do whatever you want with the data:
funcs.js
"getBooking": function (con, bookingId, callback) {
...
con.query(query, function(err, rows,fields) {
...
// instead of return booking do
callback(err, booking);
...
}
}
main module
// instead of
callback({"message": "Success","error":false, "booking": funcs.getBooking(con, bookingId)});
// do
funcs.getBooking(con, bookingId, function(err, booking) {
callback({"message": "Success","error":false, "booking": booking});
});
I am afraid this is not the only issue in your code, but this should be the first to fix. Read further about processing asynchronous calls in general and specifically in node.js and fix other places in your code correspondingly.

Check if some query is undefined and define a callback in that case

I'm trying to do something like this:
var query = 'select max(count) from ' + series +
' where value = \'' + search + '\'';
if (db.query(query, callback) !== undefined) {
return callback;
} else {
return callback = [{
name: series,
columns: ['time', 'max'],
points: [
[0, 0]
]
}];
}
I'm trying to verify if that query is undefined or the element searched doesn't exist in the influxdb, and then arm a callback just like if the element exist, the if sentence works, but the else return an empty array
The db parameter is where are the data base configurations.
EDIT:
Thanks Osukaa for your answe. I try what you sugest but don't have response. Here is the complete function with your changes:
var counter = function (config, callback) {
var count = 'select max(count) from ' + series + ' where value = \'' + search + '\'';
db.query(count, function (err, res) {
if(err) return err;
if(res.length == 0){
return [{
name: series,
columns: ['time', 'max'],
points: [
[0, 0]
]
}];
}else{
return res;
}
});
};
The console.log shows an empty array.
EDIT 2:
Thanks #Osukaa, unfortunately that don't work, this is the error that returns:
Debug: handler, error
{"msec":395.7593630000483,"error":"Couldn't find series: items.type.updated"}
Debug: internal, error
Error: Couldn't find series: items.type.updated
EDIT 3:
I've solved the problem when try to create a series. When the series don't exist, show this error 'Error Couldn't find series [series name]', so I put this code in the error code:
db.query(qCount, function(err, res) {
if (err) {
if (err == 'Error: Couldn\'t find series: ' + name.series) {
res = newSeries;
return callback(null, res);
} else {
return callback(err);
}
} else {
if (res.length !== 0) {
return callback(null, res);
} else {
res = newSeries;
return callback(null, res);
}
}
});
When the error is equal to 'Error: Couldn\'t find series: ' + name.series, I pass the values to create them.
Thanks.
Asynchronous code doesn't work like that. When the db.query is completed it will automatically execute the callback code. It isn't necessary for you to do a return callback. Instead you could try something like this:
db.query('select max(count) from ' + series +
' where value = \'' + search + '\'' + ';', function (err, res) {
if(err) return err;
if(res.length == 0){
return [{
name: series,
columns: ['time', 'max'],
points: [
[0, 0]
]
}];
}else{
return res;
}
});
EDIT
First you make the GET to obtain the count
request.get('/itemCount')
.query({value: value.type})
.end(function(err, res) {
if (err) {
reply(err);
} else {
countElemnts(res.body[0].count);
}
});
So the server goes to the route and executes the handler:
server.route({
method: 'GET',
path: '/itemCount',
handler: function(request, reply) {
events.selectCount({
series: 'value.type',
search: request.url.query.value
}, function onSuccess(err, data) {
if (err) {
reply(err);
} else {
var result = {};
if (data.length !== 0) {
result = data[0].points.map(function(element) {
return {
count: element[1] + 1
};
});
reply(null, result);
} else {
reply(null, data);
}
}
});
}
});
Which itself calls the selectCount function to obtain the number (I updated the callback to return (null,res))
var selectCount = function(config, callback) {
var qCount = 'select max(count) from ' + config.series +
' where itemType = \'' + config.search + '\'';
db.query(qCount, function(err, res) {
if (err) {
return callback(err);
}else{
if (res !== undefined) {
return callback(null,res[0]);
}else{
var res = [{
name: config.series,
columns: ['time', 'count'],
points: [
[0, 0]
]
}];
return callback(null,res);
}
}
});
};
And when the callbacks finish, it should execute countElements:
var countElemnts = function(count) {
superagent
.post(config.eventsApiUrl)
.type('json')
.send({
name: 'items.type.updated',
data: {
id: request.params.id,
itemType: item.itemType,
count: count
}
})
.end(function() {
reply({
message: 'Item actualizado'
});
});
};

Resources