nodejs function doesnt return a value [duplicate] - javascript

This question already has answers here:
How to return value from an asynchronous callback function? [duplicate]
(3 answers)
Closed 8 years ago.
I have this nodejs function, which is for inserting some data into db, and when it finishes inserting it should return 'success' or 'failure'.
This function is in the file insert.js
function insert (req,res) {
var d = req.body;
new dbModel({
name: d.dname,
desc: d.desc
}).save(false,function(err){
if (err){
return 'failure';
}else{
return 'success';
}
});
}
module.exports.insert = insert;
It inserts data into the db, but it doesnt return any value.
This is the route which invokes the above function and this is in the routes.js file.
router.post('/insert', function(req, res) {
var result = insert.insert(req,res);
res.render('insert',{title: 'insert',message: result});
});
Am I doing anything wrong or does this have something to do with async nature of nodejs.
Please help. Thanks.
EDIT
I tried as #Salehen Rahman said in the answers below, but the page isn't rendering and the browser keeps on waiting for reply from the server and i tried to log the value of result inside the callback function and again no output, it seems the code inside the callback function is not running. I checked the db and data has been inserted successfully.

That dbModel#save method is asynchronous, and so, the return keyword will only return to the inner the anonymous function. You want to use callbacks, instead. Also remove false from the save method. It can have only callback function as a parameter.
So, your insert function will look like this:
function insert (req, res, callback) {
var d = req.body;
new dbModel({
name: d.dname,
desc: d.desc
}).save(function(err){
if (err){
// Instead of return, you call the callback
callback(null, 'failure');
}else{
// Instead of return, you call the callback
callback(null, 'success');
}
});
}
module.exports.insert = insert;
And your route function will look like this:
router.post('/insert', function(req, res) {
insert.insert(req, res, function (err, result) {
res.render('insert',{title: 'insert', message: result});
});
});
Ideally, though, whenever an inner callback returns an error, you should also call your callback with the error, without any result; absent an error, and at the presence of a successful function call, you set the first parameter to null, and the second parameter to your result.
Typically, the first parameter of the callback call represents an error, where as the second parameter represents your result.
As a reference, you may want to read up on Node.js' callback pattern.

Related

Getting the result value out of Sqlite3 callback function

I'm using Sqlite3 in an Express back-end with a React front-end. So I'm trying to check if there is a user with a certain email in the database. I've got the function below, which is not finished yet, but the issue I'm having is that I cannot return the result.
Is there a way to return the result variable from the callback function or do I only have access to it inside the callback function?
When finished the function should be returning the email of the user if they exists or false if they don't exist in the database.
getUserByEmail = () => {
database.get(getUserByEmailQuery, [], (err, result) => {
if (err) {
console.log(err.message);
}
console.log(result.emailAddress);
return result;
});
};
I just solved it an hour or so ago. Not the smartest solution, but what I did was just use a different package for the database.
So I used better-sqlite3 which makes it possible to just store the result from the database query into a variable.
Here is the updated code:
exports.getUserByEmail = (email) => {
const result = betterSqlite3DB.prepare(getUserByEmailQuery).get(email);
return result;
};

async JS: why does my variable resolve to undefined? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I am getting data from my database. This works.
However, there is something wrong with the flow of my code, I think it has to do with async: Why does facturasDotaciones[ ] (almost last line of code) resolve to undefined?
//npm sql DB access module (https://www.npmjs.com/package/mssql)
var sql = require('mssql');
//sql config object (username, password, etc)
var config = {
bla, bla, bla
}
function traerFacturasDotaciones(){
var request2 = new sql.Request(connection);
request2.execute('seleccionarFacturasCorreosDotaciones', function(err, response, returnValue) {
function peluquiarFacturas(facturas){
for(var i=0;i<facturas[0].length;i++){
facturas[0][i]["CO"]=facturas[0][i]["CO"].trim();
}
return facturas;
}
return peluquiarFacturas(response);
});
}
//get data from server and clean up
var connection = new sql.Connection(config, function(err) {
var request = new sql.Request(connection);
request.execute('seleccionarTiendas', function(err, tiendasRet, returnValue) {
var facturasDotaciones=[];
facturasDotaciones=traerFacturasDotaciones();
console.log("facturasDotaciones", facturasDotaciones);
});
});
traerFacturasDotaciones() doesnt return anything. It calls request2.execute, which calls a callback function passing the response.
One option is that you pass facturasDotaciones to traerFacturasDotaciones as argument and set the value inside that function, but even then it will be assigned in asncy manner. Go through request.execute method to see if it returns promise that you can wait on ?
The function traerFacturasDotaciones does not return anything. Note that the return statement is in a callback function given as second parameter to request2.execute. But that callback is executed asynchronously, and your function traerFacturasDotaciones ends before that callback is executed.

Javascript not assign to variable [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 7 years ago.
I'm writing a basic user creation system in Node.js and I want to find out what the results of the createUser function are. The code itself works fine, with new users being posted, and already existing users being stopped. I would like to show this to the end user, so I setup a variable to return a numeric value representing what the outcome was.
The problem is, the value is never assigned to. The final console log always reads undefined, even though my other log statements appear. I feel like this is more of a JavaScript syntax question, but I am stumped.
User.prototype.createUser = function () {
console.log('Begin createUser...');
var email = this.email;
var wasUserCreated; <------- variable to assign
pg.connect(process.env.DATABASE_URL, function (err, client) {
if (err) {
console.log(err.message, err.stack);
wasUserCreated = 0; <------assigning to variable?
}
else {
var query = client.query('SELECT email FROM users WHERE email=$1', [email],
function (err, results) {
if (results.rows.length > 0) {
console.log('That email address has already been registered!');
wasUserCreated = 1; <------assigning to variable?
}
else {
console.log('Email address not found, inserting new account');
insertNewUser();
wasUserCreated = 2; <------assigning to variable?
}
});
}
});
console.log("wasUserCreated: " + wasUserCreated); <------always reads 'undefined'
return wasUserCreated;
};
This is due to your query being asynchronous - what your createUser method should do is take a callback as an argument, and invoke cb(err, wasUserCreated, user) or something inside the callback to your query.
Your console.log is always undef because it fires synchronously
some basics in mixu's node book
the 2nd argument of pg.connect is a callback function, which runs asynchronously... so the function returns before the wasUserCreated is modified

Meteor method returns null on client, same method run on client returns proper value

I got the intended behavior, but Im confused why...
I have this Meteor method, which returns the value of a document key; the log statement proves such:
findUserEmail: function(user_id){
var user = Meteor.users.find({_id: user_id}).fetch();
console.log(user[0].emails[0].address);
return user[0].emails[0].address;
}
But when I call it on the client, the shared_user_email field is null:
shared_user_email: Meteor.call('findUserEmail', $(ev.target).find('[name=shared_user]').val())
BUT, when I simulate calling the Meteor method by mimicking the server query on client, it returns the value that the Meteor method above logs:
shared_user_email: Meteor.users.find({_id: $(ev.target).find('[name=shared_user]').val()}).fetch()[0].emails[0].address
What is lost in translation when the client tries calling the server method?
EDIT
What happens when I use a Meteor method to insert a document into my collection, whose field relies on a Meteor method? I keep getting undefined for my shared_user_email field here:
var newList = {
title: $(ev.target).find('[name=title]').val(),
description: $(ev.target).find('[name=description]').val(),
dateCreated: today.toDateString(),
owner: Meteor.userId(),
owner_email: Meteor.users.find({_id: Meteor.userId()}).fetch()[0].emails[0].address,
shared_user: $(ev.target).find('[name=shared_user]').val(),
shared_user_email: Meteor.call('find_shared_user_email',
$(ev.target).find('[name=shared_user]').val(),
function(err, user_email){
return user_email;
})
}
Meteor.call('addList', newList, function(err, list){
return list;
});
On the client, you need to invoke the callback function of Meteor.call() to retrieve the value from your method.
From the documentation:
On the client, if you do not pass a callback and you are not inside a
stub, call will return undefined, and you will have no way to get the
return value of the method. That is because the client doesn't have
fibers, so there is not actually any way it can block on the remote
execution of a method.
It should work as follows:
Meteor.call(
'findUserEmail',
user_id,
function(error, result){
// 'result' here is email address from method
}
);
The code above doesn't work because you didn't get an asynchronous response from the first server call yet:
var newList = {
/* some code */
shared_user_email: Meteor.call('find_shared_user_email',
$(ev.target).find('[name=shared_user]').val(),
function(err, user_email){
/* this code is executing asynchronous */
return user_email;
})
}
/* the following call won't wait for the previous server call's completion */
Meteor.call('addList', newList, function(err, list){
return list;
});
Instead you have to make the second call only when you know for sure that the first call is finished, for example:
var newList = {
/* some code */
};
Meteor.call('find_shared_user_email',
$(ev.target).find('[name=shared_user]').val(),
function(err, user_email){
newList.shared_user_email = user_email;
Meteor.call('addList', newList, function(err, list){
/* other code to handle the added list */
});
})
}

Node.js: Asynchronous callback confusion

I am trying to figure out how to create asynchronous functions for a web app. I am doing a database query, manipulating the data to a format that is more convenient, and then trying to set my router to pass back that file.
//Module 1
//Module 1 has 2 functions, both are necessary to properly format
function fnA(param1){
db.cypherQuery(query, function(err, result){
if(err){
return err;
}
var reformattedData = {};
//code that begins storing re-formatted data in reformattedData
//the function that handles the rest of the formatting
fnB(param1, param2);
});
});
function fnB(param1, reformattedData){
db.cypherQuery(query, function(err, result){
if(err){
return err;
}
//the rest of the reformatting that uses bits from the second query
return reformattedData;
});
});
exports.fnA = fnA;
Then in my router file:
var db = require('module1');
router.get('/url', function(req,res,next){
db.fnA(param1, function(err, result){
if (err){
return next(err);
}
res.send(result);
});
});
When I tried to test this out by hitting the URL indicated by the router, it just loads indefinitely.
I know what I have above is wrong, since I never wrote my function to require a callback. When I tried figuring out how to rewrite it though, I got really confused - How do I write my function to have a callback when the asynchronous stuff happens inside it?
Can someone help me rewrite my functions to use callbacks correctly, so that when I actually use the function, I can still work with the asynchronous response?
You use db.fa from your router file, and pass the second parameter as a callback function. but the function signature don't have the cb param and doesnt use it.
The main idea - you try to initiate an async operation and cannot know when it ends, so you send it a callback function to get triggered when all operations are done.
Fixed code should be like that:
//Module 1
//Module 1 has 2 functions, both are necessary to properly format
function fnA(param1, cb1){
db.cypherQuery(query, function(err, result){
if(err){
cb1(err); <-- return error to original call
}
var reformattedData = {};
//code that begins storing re-formatted data in reformattedData
//the function that handles the rest of the formatting
fnB(param1, param2, cb1);
});
});
function fnB(param1, reformattedData, cb1){
db.cypherQuery(query, function(err, result){
if(err){
cb1(err); <-- return error to original call
}
//the rest of the reformatting that uses bits from the second query
cb1(false, dataObjectToSendBack); <--- This will call the anonymouse function in your router call
});
});
exports.fnA = fnA;
Router file:
var db = require('module1');
router.get('/url', function(req,res,next){
db.fnA(param1, function(err, result){ <-- This anonymous function get triggered last
if (err){
return next(err);
}
res.send(result);
});
});

Categories