Console loggin a MongoDB collection. Undefined [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I'm creating a Node project cause i want to knwo how to use mongoose but i'm facing a problem right now. I'm getting an undefined variable while returing a collection from my MongoDB database. This is my code:
app.js
...
case 'index-user':
let indexUserResponse = userController.index();
console.log(indexUserResponse); // undefined
break;
...
user.js (controller)
...
const index = () => {
User.find({}, function(err, res) {
if (err) throw err;
return res;
});
}
...
I know that there is a user on the database and i can see it if add a console.log(user) just before the return res; so... What is happening here? I don't get it.

The issue is that userController.index() is an calling an async function.
You should use a callback or a promise in order to fetch the data from you db.
Promise example:
Here we are returning a promise from the the executing the query on the Users collection.
const index = () => User.find({}).exec();
And in app.js:
case 'index-user':
userController.index().then(result => {
console.log(result); // as you use find there will be a list of user documents
});
break;
Or, you can use good old callbacks as so:
const index = (callback) => {
User.find({}, function(err, res) {
if (err) throw err;
return callback(res);
});
}
And in app.js:
case 'index-user':
let indexUserResponse = userController.index((result) => {
console.log(result);
});
break;
When you execute it the way you do now, the console.log() runs before the index() method can execute the find() callback.
Hope it's clear enough and helps

Related

Node.js mysql import query result outside function [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I am making a website where i need to import data from database and use it later in program. But when i am using npm package mysql i can't find any way to import result of query outside function for later use. Here is an example of my code.
Function with that i get data from database:
let output;
dba.query('SELECT * FROM `movies-web`.movies;',(err, rows) => {
if(err) {
throw err;
} else {
output = rows;
}
});
And in code i use it like this:
res.write(output);
But the variable output return undefined.
I am solving this problem for longer than month, i browsed so many pages, questions here on stackoverflow and i can't find working solution.
You can't write code like that, I suggest you read about callback documents and learn how to use asynchronous in the node is
https://nodejs.org/en/knowledge/getting-started/control-flow/what-are-callbacks/
https://www.w3resource.com/node.js/nodejs-programming-model.php
https://stackoverflow.com/a/19739852/6759368
Your code should write like that:
dba.query('SELECT * FROM `movies-web`.movies;',(err, rows) => {
if(err) {
throw err;
} else {
res.write(rows)
}
});
P.S:
A better scenario for use callback:
const http = require('http');
function executeQuery(next) {
dba.query('SELECT * FROM `movies-web`.movies;',(err, rows) => {
if(err) {
console.error(err);
next(err);
return
}
next(null, rows);
});
}
const server = http.createServer(function (req, res) {
executeQuery(function (error, output) {
if (error) {
res.writeHead(400);
res.end(error.message);
return;
}
res.writeHead(200);
res.end(JSON.stringify(output));
});
});
server.listen(8080);

Function returns "undefined" [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
My function returns "undefined", when I am waiting "result". What is a problem?
getUserDictionary = (user_id) => {
connection.connection.query("SELECT eng_word, ru_word FROM `dictionary` where user_id="+user_id,
function (error, results, fields) {
if (error) throw error;
console.log(results);
return results;
});
}
console.log(getUserDictionary(1));
"results" shows what I want (no problem with Data base connection).
But last console.log with function returns undefined
You are leaving yourself wide open to a SQL injection attack
Do not do this: "SELECT eng_word, ru_word FROM dictionary where user_id="+user_id
If this is just a pet project, fine, but if you're opening it up to the internet anyone could erase your database. Use prepared statements instead. If you are using mysqljs you can drop this in as a replacement for your current query:
connection.query('SELECT eng_word, ru_word FROM dictionary WHERE user_id = ?', [user_id], function (error, results, fields) {
Anyways...
Your problem is that connection.connection.query() is an asynchronous function. If you would like it to behave synchronously, you can use the async/await pattern supported in ES6. Otherwise, you can structure your code to act in response to the return from query().
Here is what it would look like using async/await:
getUserDictionary = (user_id) => {
return new Promise((resolve, reject) => {
connection.connection.query("blah blah blah",
function (error, results, fields) {
if (error) {
reject(error);
return;
}
console.log(results);
resolve(results);
});
});
};
Which you can use like
async () => {
let results = await getUserDictionary(0);
console.log(results);
}

How do I properly get data from an asynchronous callback method with Node/JS? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
Really sorry if this has been asked a hundred times, but I haven't been able to adapt any previous SO solutions I found to my problem. A lot of them were Ajax specific.
I'm new to asynchronous callbacks with Node, and as such I'm having an issue with properly 'returning' data from an asynchronous callback. In my example, I'm trying to return CharList. The SQL queries and the data are all valid, so those aren't too important.
I've tried simply returning the values, which I quickly learned is impossible and defeats the purpose of asynchronous callbacks.
EDIT: I've also tried defining CharList outside of the function and then assigning the values through the function, but logging CharList after the function has finished prints an empty array.
// index.js
const sql = require('./sql')
const query = require('./queries');
function AllCharsToArray() {
query.character.GetAllChars(function(result) {
let CharList = [];
for (var i in result) {
CharList.push(result[i]._Name)
}
})
}
/*
{
"characters":
[
{"_Name":"Charname 1"},
{"_Name":"Charname 2"},
{"_Name":"Charname 3"}
]
}
*/
// queries.js
const mysql = require('mysql');
const sql = require('./sql')
function GetAllChars(callback) {
sql.conn.query(`SELECT _Name FROM characters;`, function(error, results, fields) {
return callback(results); // returns RowDataPacket
})
}
exports.character = {
GetAllChars: GetAllChars,
}
Ultimately, I'm trying to get CharList to be available outside of AllCharsToArray so I can export them to an express.js route.
Suggested callback function contains error message, like
// queries.js
const mysql = require('mysql');
const sql = require('./sql')
function GetAllChars(callback) {
sql.conn.query(`SELECT _Name FROM characters;`, function(error, results, fields) {
// change as
if(error) {
return callback(error)
}
callback(null,results); // returns RowDataPacket
})
}
exports.character = {
GetAllChars: GetAllChars,
}
On index.js
...
function(req,res){
query.character.GetAllChars(function(err,data){
// check error info
if(err){
// console.debug(err)
return res.send(err.message)
}
res.json(data)
})
}
...
Placing the CharList outside the AllCharsToArray()
// index.js
const sql = require('./sql')
const query = require('./queries');
query.character.GetAllChars(function(result) {
const CharList = [];
for (var i in result) {
CharList.push(result[i]._Name);
}
// launch the route after GetAllChars is done
expressApp.get('getCharList', (req, res) => {
res.json(CharList);
});
});

How to make arrow function async? [duplicate]

This question already has answers here:
How do I convert an existing callback API to promises?
(24 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have the following code that checks the existance of a file and if present, parses the JSON data from it:
fs.access(dbPath, (err) => {
if (err) throw err
else{
console.log('Database found. Processing data.');
dbObj = processDatabaseFile(dbPath);
console.log('checkonstartup: '+dbObj);
return;
}
});
And here is the processDatabaseFile:
function processDatabaseFile(path){
fs.readFile(path, (err, data) =>{
if (err) throw err;
let jsonData = JSON.parse(data);
return jsonData;
})
}
My problem is when the fs.access function is being called, it returns sooner than the processDatabaseFile(dbPath) returns.
Eg. I want to make it use async await, but I don't know how to do that.
Tried putting async (err) => { ... declaration and then using
dbObj = await processDatabaseFile(dbPath) but it gives errors around the if-else and semicolons and missing brackets.
Feedback is appreciated.
EDIT:
About the errors regarding adding async-await. I was using VSCode and it turns out ESLint and JSHint conflicts each other.
You can make fat arrow function async using the syntax below.
const asyncFunc = async () => {
const result = await someAsyncFunc();
}
Promisify fs.readFile(), in Node you get promisify out of the box. Something like
const { promisify } = require('util');
const fs = require('fs');
const readFileAsync = promisify(fs.readFile);
fs.access(dbPath, async (err) => {
if (err) throw err
else {
console.log('Database found. Processing data.');
const dbObj = await processDatabaseFile(dbPath);
console.log('checkonstartup: ' + dbObj);
}
});
async function processDatabaseFile(path) {
const data = await readFileAsync(path);
return JSON.parse(data);
})

Hoisting / Returning variable in Javascript [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have the following code to query a MongoDB database:
var docs;
// Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
console.log("Connected successfully to server");
const db = client.db(dbName);
findDocuments(db, function() {
console.log(docs);
client.close();
});
});
const findDocuments = function(db, callback) {
// Get the documents collection
const collection = db.collection('oee');
// Find some documents
collection.find(query).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
//console.log(docs);
callback(docs);
return docs;
});
};
}
Which outputs:
Connected successfully to server
Found the following records
undefined
I want to use the results of the query which are stored inthe variable docs for further processing. However they donĀ“t get returned from the function. i.e. the the expression
findDocuments(db, function() {
console.log(docs);
client.close();
});
I get an "undefined" returned. What am I doing wrong?
You need to update the findDocuments function call as follows,
findDocuments(db, function(docs) {
console.log(docs);
client.close();
});
You don't need the docs variable at the top. Use local variables as follows,
const findDocuments = function(db, callback) {
// Get the documents collection
const collection = db.collection('oee');
// Find some documents
collection.find(query).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
return callback(docs);
});
}
Also note that I removed the return docs statement, as it doesn't have any importance along with the callback.
Finally, I suggest you to learn more about callbacks (and preferably promises)
Change this
function() {
console.log(docs);
client.close();
});
to this
function(docs) {
console.log(docs);
client.close();
});
because in your code you log docs variable on the top of your code which hadn't receive any value try the new code and tell me . does it work now ? I think yes .

Categories

Resources