Node/JSON Issues - javascript

So I am trying to figure out why my returned object every single time is just []?
Here is my code:
var returnObject = [];
db.query(queryString, function(err, rows, fields) {
if (err) throw err;
for (var i in rows)
{
console.log('Data: ', rows[i]);
var marker =
{
o_ID:rows[i].o_ID,
data:rows[i].data
};
returnObject[i]=marker;
console.log(chalk.red(returnObject[i].o_ID));
console.log(chalk.red(returnObject[i].data));
}
});
var sqsParams = {MessageBody: JSON.stringify(returnObject), QueueUrl :'---'};
For some reasons when I print the returnObject values they are correct but when it gets to the JSON.stringify something happens and sends to my SQS queue just [].
I thought maybe getting rid of the marker variable and just assigning
returnObject[i]= {
o_ID:rows[i].o_ID,
data:rows[i].data
};
But that still results in the same issue. Any ideas? Thanks!

Database queries in JavaScript are usually asynchronous. This means that the code inside your callback function function(err, rows, fields) will be run only after the database query has been done, whereas you assignment to sqsParams will be done right after the database query has been started. The result is that code inside your callback function has not been run before you returnObject with JSON.stringify and it is still in its original value [].

Your sqsParams variable is being set outside the db.query callback. As the db.query is asynchronous, your code is going to just fall through with an empty array.
Move your sqsParams variable into the callback you are supplying to db.query, eg:
console.log(chalk.red(returnObject[i].o_ID));
console.log(chalk.red(returnObject[i].data));
}
var sqsParams = {MessageBody: JSON.stringify(returnObject), QueueUrl :'---'};
// Use sqsParams here
});

Related

Why is my ipcMain returning an empty array after reading through a database?

For my project, I am using electron and react with ipcRenderer and ipcMain to communicate with a database. I can see it go through the database, but it returns an empty array. It is like the array is returned before anything is read from the db.
Here is the code I am using in my ipc main:
I am expecting it to return the names of the categories, but all it returns cateNames blank.
ipcMain.on(channels.GET_CATS, async(event,type) => {
console.log("made it")
let cateNames=[];
db.each(`SELECT name FROM categories WHERE type=?`, [type],(err, row) => {
if (err) {
return console.error(err.message);
}
console.log(row.name);
cateNames.push(row.name);
});
console.log(cateNames);
event.sender.send(channels.GET_LOGIN, cateNames);
});
I send the request with
ipcRenderer.send(channels.GET_CATS,"Donation");
with an ipcRenderer.on listening that will output the array to the console.
Javascript / Node.js execute commands in sequential order and does not "wait" when moving from one command to the next unless explicitely told to via the use of promises and async / await commands.
The reason your current code returns an empty cateNames array is becasue execution of the code does not "wait" for the db.each command to return it's callback. The callback is only returned once the DB has someting to return, which will either be a row or an error. This takes time. In the meantime, execution has moved on the next command.
To make this block of code "wait" until the DB has returned all available rows (if any) we could to use promises.
Instead, I propose a simpler method. Instead of pushing row.name with every db.each iteration, just use db.all and craft the response afterwards.
ipcMain.on(channels.GET_CATS, async(event, type) => {
console.log("made it")
let cateNames = [];
db.all(`SELECT name FROM categories WHERE type=?`, [type], (err, rows) => {
if (err) {
return console.error(err.message);
}
for (let row of rows) {
cateNames.push(row.name);
}
console.log(cateNames);
// Use event.reply(channel, data);
event.reply(channels.GET_LOGIN, cateNames);
});
});

How to make object variable changes remain after ForEach loop. Javascript

I am trying to generate a Data object that I can use to create new documents in my MongoDB database using mongoose in NodeJS.
This is the snippet of code:
console.log(RecipeData.ingredients);
RecipeData.spices.forEach(function(spice){
module.exports.findSpiceByName(spice, function(err, res){
if (err){
return callback(err);
}
RecipeData.ingredients.push(res._id);
return callback(null, RecipeData);
});
});
console.log(RecipeData.ingredients);
basically, i have RecipeData that is a object with a few attributes. the main ones in this case is spice and ingredients. both of which are list of Strings.
I want to check RecipeData.spice:
if there is a element in the list: (the element would be the name of the spice)
I want to find the spice associated to that name in my Spices Collection and add its _id to my RecipeData.ingredients permanently
both the console.log's have the same output when they shouldn't in the example I am using to test this code.
Any idea why the variable RecipeData.ingredients is not changing outside the ForEach loop?
Thanks for any help in advance.
Sounds like an asynchronous programming issue. Though you didn't post the source, I'm assuming that module.exports.findSpiceByName is asynchronous, where forEach is not, so the forEach finishes and your second console.log runs before your findSpiceByName calls have time to complete.
One way to resolve this would be to use Promises and then wait for all of them to complete before trying to inspect the ingredients:
var spicePromises = RecipeData.spices.map(function(spice) {
return new Promise(function(resolve, reject) {
module.exports.findSpiceByName(spice, function(err, res) {
if (err) {
return reject(err);
}
resolve(res._id);
});
});
});
Promise.all(spicePromises).then(function(ingredients) {
Recipe.ingredients = ingredients;
console.log(RecipeData.ingredients);
});

Unable to access the variable in NodeJs function

I am using NodeJS postgresql client to fetch some data loop through it and give an output. I'm using ExpressJS together with postgresql client.
This is my code
var main_data = some array of data
var user_info = {}
for (var key in result.rows) {
var user = main_data[key].user
client.query('SELECT name,age,address FROM users WHERE user_id = $1 LIMIT 1;' , [user], function(queryErr, result){
var return_data = result.rows[0]
user_info.name = return_data.name
user_info.gender = return_data.gender
user_info.address = return_data.address
main_data[key].user_info = user_info
})
}
done()
res.json(main_data)
return
However when I run this code I don't get a proper output. The userinfo is not pushed to the main_data. It just outputs main_data variable just as the beginning of the code.
It is not simple as the suggested duplicate
Because the function sits inside a for loop so I can't just make the response call once the function is done. I have to wait till the whole loop is finished which may be 1000+ of loops to finish before I can make the response call.
So tell me how can I achieve it.
What am I doing wrong and how can fix it?
Thank you very much
I would use async.js for this, myself.
var rows = // your result.rows stuff.
function doTheQuery(item, callback){
// your query logic here, calling the callback with the results
}
async.series(rows, doTheQuery, function(err){
// handle any errors
}

Accessing a variable that is outside an anonymous function

I have this simple code
orm: function (req, res) {
// Send a JSON response
Noder.query('SELECT * FROM crud ', function(err, results) {
var all_rows = Noder.query('SELECT count(*) from crud ', function(err, the_rows) {
return the_rows;
});
res.view('noder/orm', {
layout: 'layout',
allr:all_rows,
post:results,
title: 'This is the hi page title. '
});
});
},
which i am using to fetch all rows in a mysql table. However inside that function,i want to have another function that counts how many rows there are in the table.My variable var all_rows shows me undefined when i try displaying it. How can i solve this?.
This is because you are accessing the value of all_rows before the inner-query has returned.
Noder.query is an asynchronous function, and as such, its execution will be delayed until the query itself is completed. Meanwhile, your orm function will continue merrily down and call res.view while your inner query is still processing.
To fix this, you can call res.view from inside your inner query.

node.js global variable problematical

I don't know javascript very well. I can't define a global variable.
var data = 'empty';
connection.query('SELECT * FROM deneme',function(err, rows, fields){
if (err) throw err;
data = rows;
});
console.log(data);
Normally, console need to return rows' data but It returns 'empty'. How can I query rows from inside of function? How can I define a global variable?
The reason it is not working is because you console.log is outside the asynchronous code block. Basically what is happening is this:
data is set to empty;
connection issues a database request;
console.log fires ( data is empty at that point );
database response is received;
callback fires;
data is set to rows.
So in order to get what you want simply put console.log statement inside an asynchronous block code:
var data = 'empty';
connection.query('SELECT * FROM deneme',function(err, rows, fields){
if (err) throw err;
data = rows;
console.log(data);
});

Categories

Resources