This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I'm trying to access a local variable outside the function since a few hours. I don't know where my mistakes is. The code looks like:
Edited code:
if (lastMsg.toUpperCase().indexOf("#TEST") > -1) {
var myPythonScriptPath = 'my_script.py';
var myMessage = '';
// Use python shell
const {PythonShell} = require("python-shell");
var pyshell = new PythonShell(myPythonScriptPath);
pyshell.on('message', function (message) {
// received a message sent from the Python script (a simple "print" statement)
console.log(message);
myMessage = message;
});
// end the input stream and allow the process to exit
pyshell.end(function (err) {
if (err){
throw err;
};
});
sendText = `${myMessage};`
As a result, the variable ${message} is "undefined". The code works by itself, but inside the if statement I can't see the output of the message. How to fix that?
Apparently, sendText = `${myMessage}`; is being executed before the message is received from the listener pyshell.
pyshell.on('message', function (message) {
console.log(message);
//decide here what you want to do with the message
});
Have a look at MDN docs to understand how the asynchronous code behaves.
Update:
The trick lies in waiting until the message is received then return it, a simple solution would be in wrapping the logic in asynchronouse function and trigger a callback once the message is received.
const { PythonShell } = require("python-shell");
var pyshell = new PythonShell(myPythonScriptPath);
function getShellMessage(callback) {
pyshell.on('message', function (message) {
console.log(message);
// end listener here pyshell.end() ?
callback(null, message);
});
// end the input stream and allow the process to exit
pyshell.end(function (err) {
if (err){
callback(err);
};
});
}
// the callback function will only get triggered upon receiving the message
getShellMessage(function(err, message) {
//message is ready
console.log(message)
});
message is a variable inside of pyshell.on() and it's obvious that message is undefined outside of this block. if you want to use the value of message, you have to declare a variable outside pyshell.on() and in pyshell.on() fill that with message value.
var message="";
pyshell.on('message', function (message) {
// received a message sent from the Python script (a simple "print" statement)
console.log(message);
});
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have a nodejs server that can handle registering users. It interacts with a database and adds a new record given the values passed into it.
function registerUser(user) {
// Misc handling user
var isError = false;
userRepo.create(userData)
.catch((err) => {
isError = true
});
if (isError) {
return "Err"
}
}
The userRepo object is pretty much copied from this tutorial:
https://stackabuse.com/a-sqlite-tutorial-with-node-js/
In the catch block, I can console.log the error, but would like to return a value from the registerUser function if an error occurred. In the above code, the isError assignment inside of the catch block does not modify the isError defined above.
My question is : how can I write this so that a value indicating an error is returned from the registerUser function if an error occurs when creating the record?
That's because userRepo.create is a promise which is created and ran async, so you're getting to the last if part right away and return false.
Instead, you can return from the catch:
function registerUser(user) {
// Misc handling user
return userRepo.create(userData)
.catch((err) => {
return "Err"
});
}
In the caller, on the registerUser(user).then((res) => {... you can check the returned result and see if it's an error or not.
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.
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.
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.
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