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

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.

Related

Save the return of a callback nodejs [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 3 years ago.
I am working on the router-os library of mikrotik routers.
I'm having trouble displaying a call to the API outside the callback. The foo variable should contain the object recover in the API only I can not get around the asynchronization problem
var MikroNode = require('mikronode-ng2');
const USER = "sofian";
const PASSWD = "sofian"
var toto;
var connection = MikroNode.getConnection('10.0.0.1', USER, PASSWD)
connection.connect(function (conn) {
var chan = conn.openChannel();
conn.closeOnDone = true;
chan.write('/ip/address/print', function () {
chan.closeOnDone = true;
chan.on('done', function (data) {
var parsed = MikroNode.parseItems(data);
toto = parsed
parsed.forEach(function (item) {
console.log('Interface/IP: ' + item.interface + "/" + item.address);
})
})
})
})
console.log(toto);
return to terminal :
undefined
Interface/IP: Lan/10.0.0.1/8
Interface/IP: Wan Orange/192.168.1.254/24
Thanks
EDIT with Promise :
I try it but it still does not work
var MikroNode = require('mikronode-ng2');
const USER = "sofian";
const PASSWD = "sofian"
var connection = MikroNode.getConnection('10.0.0.1', USER, PASSWD)
var result;
function test() {
connection.getConnectPromise().then( function (conn) {
conn.getCommandPromise('/ip/address/print').then(async function resolved(values) {
// console.log('Addreses: ' + JSON.stringify(values));
result = 'Addreses: ' + JSON.stringify(values)
return await result;
})
})
}
console.log(test())
terminal :
undefined
I add async / await but it does not solve my problem
You cannot pull asynchronous data (such as data, parsed, etc) into a synchronous context. Think about it: By passing a callback to connection.connect() you're telling it "call this function at some indeterminate time in the future, when you're done connecting" and then the code continues immediately and hits console.log(toto) relatively way before the callback has executed. There is no way for data created in that callback to travel back in time.
If you want to write asynchronous code as though it were synchronous, use async/await - the library you're using does seem to support promises, so you'd have to use those functions instead to do it that way.

Why is my global variable undefined? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I am new to JavaScript. I don't get it why it prints the value undefined on the console before the correct id.
I am trying to return the inserted id yet I get an "undefined" on the return, but the console shows the correct id.
VisaFam.dbs.addFamily = function(nom) {
var db = VisaFam.dbs.db;
var family_id;
db.transaction(function(tx) {
tx.executeSql("INSERT INTO family (nom) VALUES (?)",
[nom],function(tx, results){
family_id= results.insertId; //i want to return this
console.log(results.insertId); // this prints the correct value
});
});
console.log(family_id); // this shows undefined
return family_id; // the return is thus "undefined"
}
I/O calls happens async in js and you should get returned value either from callbacks or promises:
VisaFam.dbs.addFamily = function(nom, callback) {
var db = VisaFam.dbs.db;
var family_id;
db.transaction(function(tx) {
tx.executeSql("INSERT INTO family (nom) VALUES (?)",
[nom],function(tx, results){
family_id= results.insertId; //i want to return this
console.log(results.insertId); // this prints the correct value
callback(results);
});
});
}
then call addFamily as:
addFamily(nom, function(response) {
//handle response
})
I don't have the full context of your program, but it seems that the db.transaction function is asynchronous. Because of this, the console.log() statement is running before the family_id variable has a value assigned to it.
To test this, you can change the line var family_id; to var family_id = "test";
Console should spit out "test" immediately.
To log the correct id you want, you need to move the console.log() call into the db.transaction function, which ensures the code will only execute after the value is set.

How to get data from function to variable [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
How to make a function wait until a callback has been called using node.js
(11 answers)
Closed 5 years ago.
I'm learning node.js and I have a problem. How to get data from function to variable?
function loadOrInitializeTaskArray(file, cb) {
fs.exists(file, function(exists) {
var tasks = [];
if (exists) {
fs.readFile(file, 'utf8', function(err, data) {
if (err) throw err;
var data = data.toString();
var tasks = JSON.parse(data || '[]');
cb(tasks);
})
} else {
cb([]);
}
})
}
function listTasks(file) {
loadOrInitializeTaskArray(file, function(tasks) {
for (var i in tasks) {
console.log(tasks[i]);
}
})
}
Function listTasks works correctly, but I would like create own function, for example customListTasks:
function customListTasks(file) {
var list = loadOrInitializeTaskArray(file, function(){});
console.log(list);
}
This not return me errors, but console.log on list return me "undefined". How can I get this data to variable list?
Short answer: you can not.
Because the loading in loadOrInitializeTaskArray is asynchronous, all the magic has to happen in the callback that you are passing. You cannot just 'return' a value from it.
Option 1: Place all logic that depends on the loaded data in the anonymous function that you pass as callback.
var list = loadOrInitializeTaskArray(file, function(tasks){
console.log(tasks);
});
Option 2: Use Promises. They work essentially like callbacks, but are slightly more flexible and make chaining easier.

Node.js return main loop from inside callback [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I have a function that creates an object based on db data, and some web_based json.
function makeObject(dbdata){
var obj = {};
obj.id = dbdata.id;
obj.url = dbdata.url;
request(dbdata.url,function(err,res,body){
obj.inventory = JSON.parse(body).inventory;
});
return obj
}
This obviously doesn't fill in the inventory property (async, etc...) nor does it work with the return inside request. I know the answer is pretty basic, but I just can't see it. help,please!
You can either pass in a callback argument or return a promise. request has to return a promise or you have to promisify it in some way. The callback solution is easier to get going as it stands.
function makeObject(dbdata, cb) {
/* your codes */
request(args, function (err, res, body) {
obj.inventory = JSON.parse(body).inventory;
cb(err, obj);
});
}
Then you would use it like so
makeObject(dbdata, function (err, obj) {
// handle err
// do things with obj
});

nodejs function doesnt return a value [duplicate]

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.

Categories