When you are using then
, you are dealing with asynchronous code, which means the path the program follows isn't linear. You can read more about how to return values from asynchronous calls here.
In your case, the second console.log is run before dot has been defined. That might sound strange, but the database call simply isn't finished by the time the second console.log has run. In order to use the dot value after you define it, you have to chain another then
to the same chain. Something like this:
app.post('/VerEmpresas', function (req, res) {
var r, dot, ide;
knex.from('empresas').select("id", "rut", "empresa", "razon_social", "email")
.then((rows) => {
for (row of rows) {
ide = row['id'];
knex.from('sucursales').sum("dotacion as SUM").where('id_empresas', '=', ide)
.then((q0) => {
dot = q0[0].SUM;
console.log(dot);
})
.then(() => {
console.log(dot);
// do something here with dot
})
}
res.send();
})
})
The second then
is run after the first. Usually, you pass results between then
s with return and parameters but in your case, you have declared dot with var at the top of the function which makes it available that way.
There are two more issues with your code, but it falls outside the scope of this question:
You have async calls inside a loop. This can cause issues as the loop can start all the async calls immediately. Read more about that here. I would advice you to switch to async/await, which is another way to orchestrate asynchronous calls in order to make it look like synchronous code.
You are mixing SQL and ordinary JavaScript. This might be what you want in this case, but generally writing the entire query in SQL is the way to go. Especially the for loop looks weird. Looping over the entire result of the first query is basically the same as a select.