how to call result out side the pool.query in node js - node.js

i am create node js API , getting one problem please let me know solution ,
here is my code
var searchdataArray = [];
SearchData.forEach(function(item){
SearchDataJson.KeyTags = item.hashtags;
// var d = await globalVar.data.trendingPodData();
// console.log(d);
var sql = "SELECT email , mobile from user_profile where id=228 limit 2";
pool.query(sql, function (err, result, fields) {
var myJSON = JSON.stringify(result);
var array = JSON.parse(myJSON);
SearchDataJson.Data = array;
searchdataArray.push(SearchDataJson);
console.log(searchdataArray);
});
});
my requirement is getting searchdataArray variable out side the poo.query function.

Related

How disable caching request parameters in Node js / express js

I have used a express get function to view some data. but previous parameters for request are getting stored(caching). So how do I disable caching request parameters for node js + express js. My code is given below
let driverSess;
let arrkey = 'arrkey'; let arrobj = {};
app.get('/getDriverSess', function (reqdr, res) {
var randstr = Math.random().toString(36).slice(2);//GENERATE RANDOM SESSION ID
driv = reqdr.query.driv, vehi = reqdr.query.vehi, imei = reqdr.query.imei;
var randkey = 'sessid'; var randArr = {};
var chk_Sess = drvrApp.chkAppDriverSess(driv, vehi, imei);//CHECK DRIVER SESSION
chk_Sess.then(function (result) {
driverSess = JSON.stringify(result[0].chkSess);
});
console.dir(driverSess);
if (driverSess.includes('success')) {
//save sessid
randArr[randkey] = randstr;
} else if (driverSess.includes('failure')) {
randArr[randkey] = driverSess;
}
arrobj[arrkey] = [randArr];
res.send(arrobj);
});

Firebase Database Get All Value In Order Cloud Functions

I develop for Firebase Cloud Functions. I have a Firebase Realtime Database like this:
----- myData
-------eqewrwrepere (this one is a device token)
---------Lta+sde-fer (this one is a firebase id)
firstvalue : "a"
secondvalue : "b"
----------Qrgd+ad-qdda (this one is second firebase id)
firstvalue : "c"
secondvalue : "d"
-------eqwerSAsdqe (this one is another device token)
---------Lta+sde-fer (this one is a firebase id)
firstvalue : "x"
secondvalue : "y"
----------Qrgd+ad-qdda (this one is second firebase id)
firstvalue : "z"
secondvalue : "t"
I fetch these data by this code. With this code i fetch all data and put them an array. And when fetching done, i loop this array for finding items. I am an iOS developer, so i am a newbie for NodeJS. Here is what i want to do:
Get firstvalue for each database data.
Make a api request with firstvalue of each database data.
Api returns an image.
Write image temp directory.
Process this image for visionApi.
Extract text.
Update database.
Send notification for deviceToken
Now i am able to retrieve database items in my array. When i make a request in for loop, request called async. So for loop continues, but request response or writing file and vision processing executed only once.
In for loop, get databasearray[0], make request, write file, process it with vision api, update database and go for next databasearray[1] item.
I read about Promises on different pages. But i did not understand.
Thank you.
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var request = require('request');
var fs = require('fs');
//var fs = require("fs");
// Get a reference to the Cloud Vision API component
const Vision = require('#google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
// Imports the Google Cloud client library
//const {Storage} = require('#google-cloud/storage');
var fs = require("fs");
var os = require("os");
var databaseArray = [];
exports.hourly_job = functions.pubsub
.topic('hourly-job')
.onPublish((event) => {
console.log("Hourly Job");
var db = admin.database();
var ref = db.ref("myData")
ref.once("value").then(function(allData) {
allData.forEach(function(deviceToken) {
deviceToken.forEach(function(firebaseIDs) {
var deviceTokenVar = deviceToken.key;
var firebaseIDVar = firebaseIDs.key;
var firstvalue = firebaseIDs.child("firstvalue").val();
var secondvalue = firebaseIDs.child("secondvalue").val();
var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];
databaseArray.push([...items]);
});
});
return databaseArray;
}).then(function(databasem) {
var i;
for (i = 0; i < databaseArray.length; i++) {
var databaseArrayDeviceToken = databaseArray[i][0];
console.log("DeviceToken: " + databaseArrayDeviceToken);
var databaseArrayFirebaseID = databaseArray[i][1];
console.log("FirebaseID: " + databaseArrayFirebaseID);
var databaseArrayfirstvalue = databaseArray[i][2];
console.log("firstval: " + databaseArrayfirstvalue);
var databaseArraysecondval = databaseArray[i][3];
console.log("Second: " + databaseArraysecondval);
var url = "http://api.blabla" + databaseArrayfirstvalue;
/////////////here make a request, pause loop, process returned image, but how //////////////////////
request.get({
url: url,
encoding: 'binary'
}, function(error, httpResponse, body) {
if (!error && httpResponse.statusCode == 200) {
fs.writeFileSync('/tmp/processed.jpg', body, 'binary')
console.log("file written");
})
}
});
return true;
});
I found solution with Mocas helps. Here is the solution. I use async/await functions in code. Now for loop waits for the function response. But now I have different problems. I think main async function hangs because of awaits. And then next hourly trigger, it runs again. So console log shows 15-16-17 or more ‘i’ values in for loop. I have 4 element in database array but console log shows more than this every hour. And it increases every time. So I guess that I should cancel this await functions after a timeout. But I don’t know how. Here is code:
use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var request = require('request-promise').defaults({ encoding: null });
var fs = require('fs');
// Get a reference to the Cloud Vision API component
const Vision = require('#google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
var os = require("os");
var databaseArray = [];
var uniqueFilename = require('unique-filename')
exports.hourly_job = functions.pubsub
.topic('hourly-job')
.onPublish((event) => {
console.log("Hourly Job");
var db = admin.database();
var ref = db.ref("myData")
ref.once("value").then(function(allData) {
allData.forEach(function(deviceToken) {
deviceToken.forEach(function(firebaseIDs) {
var deviceTokenVar = deviceToken.key;
var firebaseIDVar = firebaseIDs.key;
var firstvalue = firebaseIDs.child("firstvalue").val();
var secondvalue = firebaseIDs.child("secondvalue").val();
var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];
databaseArray.push([...items]);
//console.log(databaseArray);
//return true;
});
//return true;
});
return databaseArray;
}).then(function (databasem) {
main().catch(console.error);
});
return true;
});
const main = async () => {
var i;
for (i = 0; i < databaseArray.length; i++) {
console.log("Database Arrays " + i + ". elements: ");
var databaseArrayDeviceToken = databaseArray[i][0];
console.log("DeviceToken: " + databaseArrayDeviceToken);
var databaseArrayFirebaseID = databaseArray[i][1];
console.log("FirebaseID: " + databaseArrayFirebaseID);
var databaseArrayfirst = databaseArray[i][2];
console.log("first: " + databaseArrayfirst);
var databaseArraysecond = databaseArray[i][3];
console.log("second: " + databaseArraysecond);
if (databaseArrayfirst != "") {
var apiUrl = "http://api.blabla;
try {
const apiBody = await request.get(apiUrl);
///////////////////////////vison start//////////////////////
const visionResponseBody = await vision.documentTextDetection(apiBody)
var visionResponse = visionResponseBody[0].textAnnotations[0].description;
console.log("Vision response text " + visionResponse );
...some logic here about response...
/////////////////////////////////////////////////
var getdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID);
await getdatabasevar.update({
"firstvalue": visionResponse
});
/////////////////////////////////////////////////
var getanotgerdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID + "/" + "secondvalue");
await getanotgerdatabasevar.once("value")
.then(function(var) {
..some logic..
//send notification
});
} catch (error) {
console.error(error);
}
///////////////////////////vison end//////////////////////
}
};
return true;
};

Create API in node js to get data with multiple queries with my sql

I am new to node js. I am trying to develop API for getting items list by its category list. For that i have create a function to fetch all available active featured tags from table ( featured_tags ). After that featured tag list fetch i want to get items list from ( items ) table which belongs to that particular tag. Can anyone help me how to so that in node js. I am using mysql database.
i have done below things to fetch categories from table.
route.js file
this.app.get('/list_menu',async(request,response) =>{
var itemlist = '';
const featuretags = helper.getFeatureTag().then(function(featuredtags){
//console.log('test');
itemlist = helper.getitems(featuredtags);
});
response.status(200).json({
status:200,
message: "success",
data:itemlist
});
});
function to get active featured tags in helper.js file
async getFeatureTag(){
return this.db.query("select * from featured_tags where status = 1 order by id desc ");
//const featuredtags = await this.db.query("select * from featured_tags where status = 1 order by id desc ");
}
Function which get items list of featured tags in helper.js file
async getitems(featuredtags){
var itemdata = [];
var featured_tagdataset = [];
if(featuredtags.length > 0){
for (var i = 0; i < featuredtags.length; i++) {
var row = featuredtags[i];
var featurtag = {};
featurtag.id = row.id;
featurtag.featured_tag = row.featured_tag;
var itemresult = await this.db.query("SELECT * FROM `items` WHERE status = 1 and FIND_IN_SET('"+ row.id +"' ,featured_tags) > 0");
if(itemresult.length > 0){
for(var l=0; l < itemresult.length; l++){
var itemrow = itemresult[l];
var item = {};
item.id = itemrow.id;
item.category_id = row.id;
item.name = itemrow.item_name;
itemdata.push(JSON.stringify(item));
}
}
featurtag.tag_items = itemdata;
featured_tagdataset.push(featurtag);
}
//console.log(featured_tagdataset);
return featured_tagdataset;
}else{
return null;
}
}
when i console featuredtag_dataset array in itemlist() in helper.js file it show me perfect response which i have to pass in API response. But in route.js it shows me blank in data parameter.
Can anyone help me for how to develop this type of APIs in node js.
This is because helper.getitems(featuredtags) method is called successfully but send response doesn't wait until method returns a response as node js is asynchronous .
you need to write the code in such a way that it should work in series. I have created sample example you can try this.
this.app.get('/list_menu',async(request,response) =>{
helper.getFeatureTag().then(function(featuredtags){
helper.getitems(featuredtags).then(function(itemlist){
response.status(200).json({
status:200,
message: "success",
data:itemlist
});
})
}
});
You forget to use await in your roter.js on calling asynchronous function, just update your router to this
this.app.get('/list_menu',async(request,response) =>{
const featuredtags = await helper.getFeatureTag(),
itemlist = await helper.getitems(featuredtags);
response.status(200).json({
status:200,
message: "success",
data:itemlist
});
});
you can either nested callback function or async await function or chained promises using then.

Multiple queries in documentdb-q-promises for Nodejs

I want to render a page getting info for two different queries in CosmoDB using documentdb.
I have 2 queries:
var FirstQuery = {
query: 'SELECT * FROM FactoryData',
};
var SecondQuery = {
query: 'SELECT * FROM StoreData',
};
And have this to get the data
docDbClient.queryDocuments(collLink, FirstQuery ).toArray(function (err, results) {
value1 = results;
});
docDbClient.queryDocuments(collLink, SecondQuery ).toArray(function (err, results) {
value2 = results;
});
then i want to render the view with those results but i cant get it rendering from outise of this funcions.
res.render('view.html', {"value1" : value1 , "value2" : value2});
I know that this code will not work, but i was trying to implement promises and didn't know how to do it with documentdb-q-promises.
I already read a lot of documentation about Q promise but i dont get it.
Can someone explain to me how i can do it , I`m a beginner.
Based on your requirements,I followed the npm doc and test code on github to test following code in my local express project. Please refer to it.
var express = require('express');
var router = express.Router();
var DocumentClient = require('documentdb-q-promises').DocumentClientWrapper;
var host = 'https://***.documents.azure.com:443/'; // Add your endpoint
var masterKey = '***'; // Add the massterkey of the endpoint
var client = new DocumentClient(host, {masterKey: masterKey});
var collLink1 = 'dbs/db/colls/import';
var FirstQuery = 'select c.id,c.name from c';
var collLink2 = 'dbs/db/colls/item';
var returnArray = [];
client.queryDocuments(collLink1, FirstQuery).toArrayAsync().
then(function(response){
console.log(response.feed);
var map = {};
map['value1'] = response.feed;
returnArray.push(map);
return client.queryDocuments(collLink2, FirstQuery).toArrayAsync()
})
.then(function(response) {
console.log(response.feed);
var map = {};
map['value2'] = response.feed;
returnArray.push(map);
})
.fail(function(error) {
console.log("An error occured", error);
});
router.get('/', function(req, res, next) {
res.send(returnArray);
});
module.exports = router;
Test Result:
Hope it helps you.

Unable to get variable from module exports

I have a connector.js file which using which I want to export dbResult object.
(function(){
var Massive = require("massive");
var connectionString = "postgres://postgres:postgres#localhost/postgres";
var db = Massive.connectSync({connectionString : connectionString});
var dbResult ;
db.query("Select * from company", function (err, data) {
dbResult = data;
console.log(data);
});
})(module.exports);
Now in Another file I am trying to get the dbResult and display the data:
var express = require("express");
var app = express();
var connectorObject = require("./Connector.js");
var Massive = require("massive");
app.get("/api/Steves",function(req,res){
res.set("Content-Type","application/json");
res.send(connectorObject.dbResult);
});
app.listen(3000);
console.log("Server Started on port 3000...");
But when I start the URL , not able to see any response .
Am I missing anything here.
What you want to do, is return a function that can be evaluated later for the result:
var Massive = require("massive");
var connectionString = "postgres://postgres:postgres#localhost/postgres";
var db = Massive.connectSync({connectionString : connectionString});
module.exports.getCompanies = function(callback) {
db.query("Select * from company", callback);
}
Then you can access it from your other files as:
var connector = require('./Connector');
connector.getCompanies(function( err, data ) {
if ( err ) return console.error( err );
console.log( data );
});

Resources