I am trying to make multiple http get requests in nodeJs. I need to continue getting records until there are no more available. I am having problems trying to do the iteration of a chunk of code. I had been reading about the async module but I am not understanding how to apply it. Please help.
Here is the New code 11/25/2014:
The step I want to repeat is the GetUrl(newBlock) is the step I want to repeat until there is no more blocks. I determine that there is no more blocks when the result.lenght of the request response is less than 5,000.
Is there a way of me getting this parameter pack from newBlock function and then stop the loop if I use the whilst async module?
// JS Script: GPSAPIClient
// Code Description: API client code to retrieve GPS data for customer with account number: 47631
// This script requires Node.Js environment installed with Request() and Node-crontab modules (through NPM).
// It will run (as a backend script) every minute and retrieve the GPS available.
//
// Author : Vanessa Torres, Professional Services
var request = require("request");
var fs = require('fs');
var async = require('async');
var crontab = require('node-crontab');
var csvFile = "";
var debug = false;
process.argv.forEach(function(val, idx, array) {
if (val.toLowerCase() === 'debug') {
debug = true;
console.log('\n\n\n******************DEBUG MODE ACTIVE(Do not run in prod)******************\n\n\n')
}
});
console.log('waiting to start running');
var jobId = crontab.scheduleJob('* * * * *', function() {
//Gettting system date and adding leading zeros when are single digits. I need this to build the get request with date filters.
var d = new Date();
var nday = d.getDate();
var nmonth = d.getMonth();
var nhour = d.getHours();
var nmin = d.getMinutes();
var nfullyear = d.getFullYear();
if (nday < 10) {
nday = '0' + nday;
};
//1 minute substraction except for when is zero (the value will negative).
if (nmin != 0) {
var nmin = nmin - 1;
};
if (nmin < 10) {
nmin = '0' + nmin;
};
// added because TLC Plumbing is 2 hours behind us. (MST)
nhour = nhour - 2;
if (nhour < 10) {
nhour = '0' + nhour;
};
var nmonth = nmonth + 1;
if (nmonth < 10) {
nmonth = '0' + nmonth;
};
var options = {
//url: 'https://credentials#api.comettracker.com/v1/gpsdata' + '?fromdate=' + nfullyear + '-' + nmonth + '-' + nday + 'T' + nhour + '%3a' + nmin + '%3a' + '00',
url: 'https://credentials#api.comettracker.com/v1/gpsdata?fromdate=2015-11-23T17%3a00%3a00&todate=2015-11-24T10%3a00%3a00',
method: 'GET',
rejectUnauthorized: !debug
};
function GetUrl(callback) {
return request(options, function(error, response, body) {
console.log('request for links');
if (error) throw new Error(error);
var result = JSON.parse(body)['links'];
var urlnext = result[2].href;
console.log('UrlNext: ' + urlnext);
console.log(result[2].rel);
//moreBlocks = newBlock(urlnext);
moreBlocks = callback(urlnext);
});
// request to get the next block of records (maximun 5,000)
};
// HTTP get request - 1st request
request(options, function(error, response, body) {
if (error) throw new Error(error);
var result = JSON.parse(body)['gps-recs'];
console.log(result.length);
//console.log(result);
//create .csv file if result.length is > = 1 (If we received GPS records)
if (result.length >= 1 && result.length < 5000) {
console.log('entered first if, result.length: ' + result.length);
buildCSV(result);
};
//add the subsequent request when result.length = 5000
if (result.length == 5000) {
console.log('entered second if, result.length: ' + result.length);
buildCSV(result);
console.log('I came back from buildCSV. result.length is : ' + result.length);
**GetUrl(newBlock)**;
//console.log('moreblocks back from newblock: ' + moreBlocks);
};
});
});
function newBlock(urlnext) {
console.log('URL passed to newBlock: ' + urlnext);
// option 2 - variables needed to built the url (like the first request)
var n = urlnext.length;
var rest = urlnext.substr(40, n);
console.log('Rest: ' + rest);
var options = {
url: 'https://credentials#api.comettracker.com/v1/gpsdata/' + rest,
method: 'GET',
rejectUnauthorized: !debug
};
request(options, function(error, response, body) {
console.log('nextblock request');
if (error) throw new Error(error);
var result = JSON.parse(body)['gps-recs'];
if (result.length == 0) {
//no records for filter
console.log('first if' + result.length);
moreBlocks = false;
};
if (result.length < 5000 && result.length > 0) {
//last block appends record and ends
appendCSV(result);
moreBlocks = false;
console.log('second if' + result.length);
};
if (result.length == 5000) {
//appends records but has to keep running
appendCSV(result);
console.log('third if- moreBlocks' + result.length);
};
console.log('moreBlocks: ' + moreBlocks);
});
};
function buildCSV(result) {
var csvFile = " ";
console.log('before csvFile: ' + csvFile);
//adding headers
csvFile = csvFile.concat('UserNumber' + ',' + 'UserTimeTag' + ',' + 'Latitude' + ',' + 'Longitude' + ',' + 'SpeedMph' + ',' + 'Heading' + ',' + 'Status' + '\r\n');
// loop runs result.length times
for (var i = 0; i < result.length; i++) {
csvFile = csvFile.concat(result[i].UserInfo.UserNumber + ',' + result[i].UserTimeTag + ',' + result[i].Latitude + ',' + result[i].Longitude + ',' + result[i].SpeedMph + ',' + result[i].Heading + ',' + result[i].Status + '\r\n');
};
//console.log(csvFile);
fs.writeFile('file.csv', csvFile, function(err) {
if (err) throw err;
console.log('file saved');
});
};
//appending additional blocks
function appendCSV(result) {
var csvString = " ";
// loop runs result.length times
for (var i = 0; i < result.length; i++) {
csvString = csvString.concat(result[i].UserInfo.UserNumber + ',' + result[i].UserTimeTag + ',' + result[i].Latitude + ',' + result[i].Longitude + ',' + result[i].SpeedMph + ',' + result[i].Heading + ',' + result[i].Status + '\r\n');
};
// console.log(csvString);
fs.appendFile('file.csv', csvString, function(err) {
if (err) throw err;
console.log('Data appended');
});
};
It is difficult to see if moreBlocks is in the same scope as the while. On the other hand, the while statement will start making calls indefinetilly until that flags changes, and that might be too late. You need to make sure you do each subsequent request at a time.
You could use async's ´whilst´ function:
var moreBlocks = true;
whilst(function(){
return moreBlocks === true;
},function(callback){
return request(options, function(err, res, body){
console.log('request for links');
if (err) throw new Error(err);
var result = JSON.parse(body)['links'];
var urlnext = result[2].href;
console.log('UrlNext: ' + urlnext);
console.log(result[2].rel);
//You NEED to make sure you update moreBlocks
moreBlocks = newBlock(urlnext);
// Go to next step.
return callback(res);
})
},{
//You are done!
//Call any function you'd like.
});
Check the docs here!
Edit, if newBlock is asynchronous:
var moreBlocks = true;
whilst(function(){
return moreBlocks === true;
},function(callback){
return request(options, function(err, res, body){
console.log('request for links');
if (err) throw new Error(err);
var result = JSON.parse(body)['links'];
var urlnext = result[2].href;
console.log('UrlNext: ' + urlnext);
console.log(result[2].rel);
//Now status has the info about moreBlocks.
return newBlock(urlnext, function(status){
moreBlocks = status;
// Go to next step.
return callback(res);
});
})
},{
//You are done!
//Call any function you'd like.
});
Somewhere on newBlock:
function newBlock(urlnext, callback) {
// some code..
return request(options, function(){
//here status decides if we are done.
return callback(status);
});
}
Related
I'm trying to get some data from a lot of URLs using 'request', but I can't manage to do it one url at a time.
I've tried to understand async/promises in order to make it work, but with no success. Trial and error didn't work.
I've seen other methods using different modules, but this requires rewriting most of my code and I believe there is an easier way to adapt it to my current code.
Here is a minimized version of the code :
const request = require('request');
const fs = require('fs');
const prod = fs.readFileSync('prod.txt', "utf8");
const prodid = prod.split("|");
var i;
var summary=[];
for (i=0;i<prodid.length;i++){
request('https://www.api.example.com/id='+prodid[i], { json: true }, (err, res, body) => {
if (err) { return console.log(err); }
if (body == 'NULL') {
console.log("Page " + i + " out of " + prodid.length + " is NULL!");
} else {
summary.push(body.items[0].Name);
summary.push(body.items[0].ISOnr);
summary.push(body.items[0].GTIN);
console.log("Page " + i + " out of " + prodid.length + " is done!");
fs.appendFileSync('data.txt',JSON.stringify(summary));
}
});
}
There is no async/promise involved in the example above, just the requests inside a loop.
From what I've seen, when I get the results, there is no particular order (probably is the order of which finishes first).
In the console, I always see page 500 out of 500, not 1/500, 2/500, etc.
What I'm trying to achieve, is by making each request in the order of URLs (preferably with a 1000ms delay between them)
You can promisify your request:
for (i = 0; i < prodid.length; i++) {
const result = await new Promise((resolve, reject) =>
request(
'https://www.api.example.com/id=' + prodid[i],
{ json: true },
(err, res, body) => {
if (err) {
reject(err);
}
if (body == 'NULL') {
console.log('Page ' + i + ' out of ' + prodid.length + ' is NULL!');
} else {
resolve(body);
}
}
)
);
if (result) {
summary.push(result.items[0].Name);
summary.push(result.items[0].ISOnr);
summary.push(result.items[0].GTIN);
console.log('Page ' + i + ' out of ' + prodid.length + ' is done!');
fs.appendFileSync('data.txt', JSON.stringify(summary));
}
}
I made this function that retrieve the flight data from Aviationstack API(a flight API ). I'm new to nodejs and I want to make this function synchronous using 'sync-request' so that when I call anywhere I could get something in return. here is the function code :
function get_flights_by_date(date) {
let url = 'http://api.aviationstack.com/v1/flights?access_key=xxxxxxxxxxxxxxxxx&flight_status=scheduled'
request(url, function (err, response, body) {
if (err) {
console.log('error:', error);
} else {
let vol = JSON.parse(body)
num = vol.pagination.limit
for (let i = 0; i < num; i++) {
dep = vol.data[i].departure.airport
depart = vol.data[i].departure.timezone
arrival = vol.data[i].arrival.timezone
arr = vol.data[i].arrival.airport
flight_date = vol.data[i].flight_date
number = vol.data[i].flight.number
console.log('flight number:' + ' ' + number + ' ' + 'from' + ' ' + depart + ' ' + 'at' + ' ' + dep + ' ' + 'airport' + ' ' + 'to' + ' ' + arrival + ' ' + 'at' + ' ' + arr + ' ' + 'airport' + ' ' + 'on' + ' ' + flight_date + '.')
}
}
});
}
This is not a way to make a sync code in node js
There are few approach to make any code sync
callback
What you are doing, this will fail when you will call directly from other function. instead you can do this
function get_flights_by_date(date, callback) {
let url = 'http://api.aviationstack.com/v1/flights?access_key=xxxxxxxxxxxxxxxxx&flight_status=scheduled'
request(url, function (err, response, body) {
if (err) {
console.log('error:', error);
callback(err);
} else {
let vol = JSON.parse(body)
num = vol.pagination.limit
for (let i = 0; i < num; i++) {
dep = vol.data[i].departure.airport
depart = vol.data[i].departure.timezone
arrival = vol.data[i].arrival.timezone
arr = vol.data[i].arrival.airport
flight_date = vol.data[i].flight_date
number = vol.data[i].flight.number
console.log('flight number:' + ' ' + number + ' ' + 'from' + ' ' + depart + ' ' + 'at' + ' ' + dep + ' ' + 'airport' + ' ' + 'to' + ' ' + arrival + ' ' + 'at' + ' ' + arr + ' ' + 'airport' + ' ' + 'on' + ' ' + flight_date + '.')
}
callback(null, number)
}
});}
function mainFunction(){
var date = '';
get_flights_by_date(date, function(err, result){
if(err){
return err
}
return result
})
}
promise
function get_flights_by_date(date) {
return new Promise(function (resolve, reject) {
let url =
"http://api.aviationstack.com/v1/flights?access_key=xxxxxxxxxxxxxxxxx&flight_status=scheduled";
request(url, function (err, response, body) {
if (err) {
console.log("error:", error);
reject(err);
} else {
let vol = JSON.parse(body);
num = vol.pagination.limit;
for (let i = 0; i < num; i++) {
dep = vol.data[i].departure.airport;
depart = vol.data[i].departure.timezone;
arrival = vol.data[i].arrival.timezone;
arr = vol.data[i].arrival.airport;
flight_date = vol.data[i].flight_date;
number = vol.data[i].flight.number;
}
resolve(number);
}
});});
}
async function main() {
try {
await get_flights_by_date("");
} catch (error) {}
}
Async lib
or you can use this lib to do your entire code here https://medium.com/velotio-perspectives/understanding-node-js-async-flows-parallel-serial-waterfall-and-queues-6f9c4badbc17
I would recommend you to go for async lib as it is easy to scale in this fashion
I would totally avoid using synchronous code when ever possible, as this does not scale. This is a very bad practice, and will halt your server as long as the request is still fetching...
You can (And should) use async/await, or Promise to wait for the data while making sure your server is available.
If you want to avoid the then callback on Promise, just use async/await
Converted to use Promise and async/await:
function get_flights_by_date(date) {
const url = 'http://api.aviationstack.com/v1/flights?access_key=xxxxxxxxxxxxxxxxx&flight_status=scheduled'
return new Promise((resolve, reject) => {
request(url, (err, response, body) => {
if (err) {
reject(err);
} else {
const data = JSON.parse(body); // Process your data
resolve(data);
}
});
})
}
function promiseExample() {
get_flights_by_date(new Date()).then(resultData => console.log(resultData))
}
async function example() {
const resultData = await get_flights_by_date(new Date());
console.log(resultData);
}
I get this error:
fs.js:81 throw new TyperError('Expected options to be either an object or a string. )
It doesn't do it on my mac but it does it on windows.
I'm not sure how to troubleshoot this, I don't know nodejs well
Here's the entirety of my code, not sure where the problem is as I use fs in several places
// load modules
var request = require('request');
// create text file on disk
var filename = Date.now(); // date for filename
var fs = require('fs'); // code to make file
fs.writeFile("" + filename + ".csv", "", function(err) {
if (err) {
return console.log(err);
}
console.log("The file " + filename + ".csv was created!");
}); // create text file on disk end
// read urls file
var fs = require("fs");
fs.readFile("urls.txt", function(err, f){
var urls = f.toString().split('\n');
console.log("Finished reading URLs file...")
// use the array
// loop through every file
for (var i = 0; i < urls.length; i++) {
console.log('\x1b[32m%s\x1b[0m',"Loaded to memory -> ",urls[i]);
setTimeout(main, i * 300, urls[i], i, urls.length);
}// end loop
}); // read urls end
console.log("Loop done...");
function main (url, lineNumber, totalLines) {
// get request to url
request(url, function (error, response, body) {
if (typeof response == 'undefined' || response == null) {
return;
}
if (response.statusCode !== 200) { return; }
// console.log('error:', error); // Print the error if one occurred
console.log('\x1b[2m%s\x1b[0m','StatusCode for ' + url + ' ->', response && response.statusCode); // Print the response status code if a response was received
// console.log('body:', body); // Print the HTML for the Google homepage.
//define my regex
var myregex = /href="([^"]*contact[^"]*)"/gi;
// make sure it's not null
if (typeof body == 'undefined' || body == null || body.match(myregex) == 'undefined' || body.match(myregex) == null){
return;
}
// find contact urls using regex and puts it in array
results = body.match(myregex).slice(1);
// console.log(results);
//loop through arrays of regexes
for (var x = 0; x < results.length; x++) {
//remove href from string
results[x] = results[x].replace('href="', '');
results[x] = results[x].replace('"', '');
//add root domain if it doesn't have it
if (results[x].match(/http/) == null) {
//trim to root
trim = RegExp(/(http:\/\/|https:\/\/).+?\//);
console.log("Has no root -> " + url);
url = url.match(trim)[0];
console.log("Trimming domain... Done -> " + url);
//add domain
results[x] = url + results[x];
//clean double slashes
results[x] = results[x].replace(/([^:])(\/\/+)/g, '$1/');
console.log("Adding root complete -> " + results[x]);
}
else {
console.log("Found contact url for " + url + " -> " + results[x]);
}
// writing to disk
var fs = require('fs');
fs.appendFileSync(filename + ".csv",lineNumber + "," + results[x] + "\n", function(err) {
if (err) {
return console.log(err);
}
}); // writing to disk end
console.log('\x1b[32m%s\x1b[0m', "Added to the text file " + filename + ".csv " + results[x] + " (" + lineNumber + " of " + totalLines + " " + Math.floor((lineNumber / totalLines) * 100) + "% completed!)");
}
}); // end get request to url
}; //end main
appendFileSync does not accept a callback as argument. Replace it by appendFile. Ref.: https://nodejs.org/api/fs.html#fs_fs_appendfile_file_data_options_callback
//Created a promise for each image size.
var promises = sizes.map(function (size) {
return new Promise(function (resolve, reject) {
var destinationDir = fileUtil.getAbsolutePathOfImage(destinationPath);
fileUtil.createDirectoryIfNotExists(destinationDir);
destinationDir += size.src;
fileUtil.createDirectoryIfNotExists(destinationDir);
//Resize the image.
//console.log('imagefile : ' + JSON.stringify(imageFile));
//console.log('destinationDir: ' + JSON.stringify(destinationDir));
//Called an imageUtil resize method to perform resize.
imageUtil.resize(imageFile, destinationDir, size).then(data => {
var fileName = destinationPath + size.src + '/' + data;
resolve(imageUtil.createImageData(fileName, size.height, size.width));
}).catch(err => {
console.error(err);
return reject(err);
});
});
});
Promise.all(promises)
.then(savedImages => {
console.log('saved Images are: ' + JSON.stringify(savedImages));
return res.status(200).json(savedImages);
}).catch(err => {
console.log('i am here' + JSON.stringify(err.message));
return res.status(400).json(JSON.stringify(err.message));
});
---------------------Resize method of imageutil---------------
var Promise = require('bluebird'),
gm = require('gm'),
path = require('path'),
fs = require('fs');
Promise.promisifyAll(gm.prototype);
module.exports = {
resize(imageFile, destinationPath, size){
if (!imageFile || !destinationPath || !size) {
return;
}
return new Promise(function (resolve, reject) {
// If we just passed callback directly, errors would be fatal
var fileName = fileUtil.getFileName(imageFile);
//console.log('sourceFile : ' + JSON.stringify(imageFile));
//console.log('saveDirectory : ' + JSON.stringify(destinationPath));
//console.log('fileName is :' + fileName);
//Create a write stream.
var writeStream = fs.createWriteStream(destinationPath + '/' + fileName);
//console.log('Saving at location: ' + writeStream.path);
gm(imageFile)
.resize(size.width, size.height, '^')
.gravity('Center')
.crop(size.width, size.height)
.writeAsync(writeStream.path, function (err) {
if (err) {
var error = 'Error while creating image of resolution : ' + size.width + 'x' + size.height + '.';
console.error(JSON.stringify(error));
return reject(new Error(error));
}
});
resolve(fileName);
});
}
};
*It seems like everything went correct and it creates four image file which is corrupted and gave me error later on but request processed succesfully. Console output of my image processing are as follows:
saved Images are: [{"src":"/uploads/300/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"200","width":"300"},{"src":"/uploads/120/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"120","width":"120"},{"src":"/uploads/48/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"48","width":"48"}]
POST /api/upload/image/ 200 51.790 ms - 241
"Error while creating image of resolution : 120x120."
"Error while creating image of resolution : 48x48."
"Error while creating image of resolution : 300x200."*
Since you are already using promisifyAll, you don't need to (and should not) use the Promise constructor. writeAsync already returns a promise - if you don't pass a callback, as that's the requirement for Bluebird being able to pass the callback itself in the right position.
You should be using
module.exports = {
resize(imageFile, destinationPath, size){
if (!imageFile || !destinationPath || !size) {
return Promise.reject(new Error("missing arguments"));
}
var fileName = fileUtil.getFileName(imageFile);
//console.log('sourceFile : ' + JSON.stringify(imageFile));
//console.log('saveDirectory : ' + JSON.stringify(destinationPath));
//console.log('fileName is :' + fileName);
//Create a write stream.
var writeStream = fs.createWriteStream(destinationPath + '/' + fileName);
//console.log('Saving at location: ' + writeStream.path);
var promise = gm(imageFile)
.resize(size.width, size.height, '^')
.gravity('Center')
.crop(size.width, size.height)
.writeAsync(writeStream.path);
return promise.then(function() {
return filename;
}, function (err) {
var error = 'Error while creating image of resolution : ' + size.width + 'x' + size.height + '.';
console.error(error, err);
throw new Error(error);
});
}
};
Similarly, you shouldn't use the Promise constructor antipattern in the call to resize - it already returns a promise:
var promises = sizes.map(function (size) {
var destinationDir = fileUtil.getAbsolutePathOfImage(destinationPath);
fileUtil.createDirectoryIfNotExists(destinationDir);
destinationDir += size.src;
fileUtil.createDirectoryIfNotExists(destinationDir);
//Resize the image.
//console.log('imagefile : ' + JSON.stringify(imageFile));
//console.log('destinationDir: ' + JSON.stringify(destinationDir));
return imageUtil.resize(imageFile, destinationDir, size)
//^^^^^^
.then(data => {
var fileName = destinationPath + size.src + '/' + data;
return imageUtil.createImageData(fileName, size.height, size.width));
}, err => {
console.error(err);
throw err;
});
});
I am using node js script to sync data(for multiple users) from GeoTab server APIs to my local db and using below code
var syncUsers = function () {
for (var i = 0; i < geotabUsers.length; i++) {
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);
}
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);
}
var syncStatusData = function (api, i, fromVersion, userId, currentCompany, apiUsername, apiPassword, apiDatabase){
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);
return;
}
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 thisDate = moment(new Date(data.data[key].dateTime));
var thisDayDate = thisDate.format("YYYY-MM-DD");
//prepare data to insert
var insertRow = [
currentCompany,
thisDate.format("YYYY-MM-DD HH:MM:ss"),
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);
var todayDate = moment(new Date());
var todayDayDate = todayDate.format("YYYY-MM-DD");
//send alert in case of current day data
if (todayDayDate == thisDayDate)
{
//send mails in case of high pressure
if (diagnosticList[data.data[key].diagnostic.id].unitOfMeasure == js_lang.GEOTAB_PRESSURE_UNIT_STR &&
data.data[key].data > js_lang.MAX_PRESSURE &&
alertTemplates[userId] != undefined)
{
console.log('alert time');
if (alertTemplates[userId] != undefined)
{
for (var templateIndex = 0; templateIndex < alertTemplates[userId].length; templateIndex++) {
var template = alertTemplates[userId][templateIndex];
var res = template.devices.split(",");
var index = FUNCTION_CLASS.contains.call(res, data.data[key].device.id)
if (index)
{
var emailSubject = 'High Pressure Alert';
if (userDevices[userId][data.data[key].device.id].name != undefined)
{
var emailText = 'Vehicle:' + userDevices[userId][data.data[key].device.id].name;
}
else
{
var emailText = '';
}
var toEmails = template.emails;
var emailHtml = 'Vehicle:' + userDevices[userId][data.data[key].device.id].name + '<br>' + diagnosticList[data.data[key].diagnostic.id].name + ' <br> value:' + data.data[key].data + ' ' + js_lang.GEOTAB_PRESSURE_UNIT_PA + '<br>\
' + js_lang.DATE_TIME + ':' + thisDate.format("YYYY-MM-DD HH:MM:ss");
//call mail function
sendEmail(toEmails, emailSubject, emailText, emailHtml);
}
}
}
}
}
}
}
if (insertStatus.length > 0)
{
connection.query(sql, [insertStatus], function (err) {
if (err)
throw err;
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');
continueSync();
}
});
}
catch (e) {
continueSync();
}
}
var continueSync = function () {
setTimeout(function () {
connection.end();
geotabUsers = [];
userDevices = [];
diagnosticList = [];
userInfo = [];
alertTemplates = {};
eventEmitter.emit('getUsers');
}, 60000);
}
Its work fine for few iteration but getting random errors like
events.js:85
throw er; // Unhandled 'error' event
^
Error: Quit inactivity timeout
Or
events.js:85
throw er; // Unhandled 'error' event
^
Error: Connection lost: The server closed the connection.
I was getting this error while executing app on local, To remove problem I have used pm2 node module for process management.Now its working fine.