英文:
NodeJs returned array from database query is undefined
问题
The issue you're facing seems to be related to asynchronous behavior in your Node.js application. The problem lies in the fact that getSubData
function is asynchronous and does not wait for the database query to finish before returning the result. As a result, arows
is undefined
when you try to access its length
property in the getData
function.
To fix this, you need to handle the asynchronous nature of the database queries. One way to do this is by using Promises or async/await. Here's an example using async/await:
module.exports = {
getData: async () => {
let dbc = require('./mods/db.js');
try {
let rows = await module.exports.getSubData();
console.log('arows.length:', rows.length);
} catch (err) {
console.log('Error 1:', err);
}
},
getSubData: () => {
return new Promise((resolve, reject) => {
let dbc = require('./mods/db.js');
dbc.query(`
SELECT 10 rn, 'Ten' rt UNION
SELECT 20 rn, 'Twenty' rt UNION
SELECT 30 rn, 'Thirty' rt ;
`,
function (err, rows) {
if (err) {
reject(err);
} else {
console.log('arows:', rows.length);
resolve(rows);
}
});
});
}
}
In this modified code, the getSubData
function returns a Promise that resolves with the database query result. The getData
function is now declared as async
and uses await
to wait for the getSubData
function to complete before proceeding.
This should solve the issue you're experiencing with the undefined
value of arows
.
英文:
An NodeJs app we are wrting has a problem with the query data returned as an array being undefined
. I cannot find an exact match for our issue.
The following test case reproduces the problem. It is something to do with the calling function not waiting for the called function to finish? I'm not a JavaScript expert, and this behaviour does not make sense to me.
themod.js
module.exports = {
getData: () => {
let dbc = require('./mods/db.js');
dbc.query(`
SELECT 1 rn, 'One' rt UNION
SELECT 2 rn, 'Two' rt UNION
SELECT 3 rn, 'Three' rt ;
`,
function (err, rows) {
if (err) {
console.log ( ' Error 1: ' , err );
} else {
arows = module.exports.getSubData();
console.log ( 'arows.length: ', arows.length );
}
})
},
getSubData: () => {
let dbc = require('./mods/db.js');
dbc.query(`
SELECT 10 rn, 'Ten' rt UNION
SELECT 20 rn, 'Twenty' rt UNION
SELECT 30 rn, 'Thirty' rt ;
`,
function (err, rows) {
if (err) {
console.log ( ' Error 3: ' , err );
} else {
console.log ( 'arows: ', rows.length );
return( rows );
}
})
}
}
theapp.js:
let tm = require('./themod.js');
tm.getData();
When it's run:
node theapp.js
/path/node/node_modules/mysql/lib/protocol/Parser.js:437
throw err; // Rethrow non-MySQL errors
^
TypeError: Cannot read property 'length' of undefined
at Query.<anonymous> (/path/node/themod.js:17:54)
at Query.<anonymous> (/path/node/node_modules/mysql/lib/Connection.js:526:10)
at Query._callback (/path/node/node_modules/mysql/lib/Connection.js:488:16)
at Query.Sequence.end (/path/node/node_modules/mysql/lib/protocol/sequences/Sequence.js:83:24)
at Query._handleFinalResultPacket (/path/node/node_modules/mysql/lib/protocol/sequences/Query.js:149:8)
at Query.EofPacket (/path/node/node_modules/mysql/lib/protocol/sequences/Query.js:133:8)
at Protocol._parsePacket (/path/node/node_modules/mysql/lib/protocol/Protocol.js:291:23)
at Parser._parsePacket (/path/node/node_modules/mysql/lib/protocol/Parser.js:433:10)
at Parser.write /path/node/node_modules/mysql/lib/protocol/Parser.js:43:10)
at Protocol.write (/path/node/node_modules/mysql/lib/protocol/Protocol.js:38:16)
As requested, mods/db.js:
var mysql = require('mysql');
var dbConn = mysql.createConnection({
host : 'localhost',
user : 'unam',
password : 'pwrd',
database : 'dbname'
});
dbConn.connect ( function(err) {
if (err) {
console.error( "DB Connect failed ", err);
}
});
module.exports = dbConn;
答案1
得分: 0
I think your problem comes from the scope of your getSubData function.
你的问题可能来自于 getSubData 函数的作用域。
You do not return anything; you return rows in the callback function, but nothing at the getSubData level.
你没有返回任何东西;你在回调函数中返回了行,但在 getSubData 层级中没有返回任何东西。
That's why it returns null, and then .length cannot be read.
这就是为什么它返回 null,然后无法读取 .length。
You can try with this:
你可以尝试使用这个:
getSubData: () => {
let dbc = require('./mods/db.js');
return dbc.query(`
SELECT 10 rn, 'Ten' rt UNION
SELECT 20 rn, 'Twenty' rt UNION
SELECT 30 rn, 'Thirty' rt ;
`,
function (err, rows) {
if (err) {
console.log('Error 3:', err);
} else {
console.log('rows:', rows.length);
return rows;
}
})
}
You will then get the full query and the result inside.
然后,你将在内部获得完整的查询和结果。
So regarding functions synchronization, you are good; it is more a matter of scope.
所以,关于函数同步,你是正确的;这更多是关于作用域的问题。
This example should work:
这个示例应该可以工作:
const function1 = () => {
const function2 = () => {
return 'something';
}
return function2;
}
You wrote:
你写的是:
const function1 = () => {
const function2 = () => {
return 'something';
}
//nothing returned for function1
}
英文:
I think your problem come from the scope of your getSubData function.
You do not return anything, you return row in the callback function but nothing at the getSubData level.
That's why arrow return null and then .length cannot be red.
You can try with this
getSubData: () => {
let dbc = require('./mods/db.js');
return dbc.query(`
SELECT 10 rn, 'Ten' rt UNION
SELECT 20 rn, 'Twenty' rt UNION
SELECT 30 rn, 'Thirty' rt ;
`,
function (err, rows) {
if (err) {
console.log ( ' Error 3: ' , err );
} else {
console.log ( 'arows: ', rows.length );
return( rows );
}
})
}
you will then get the full query and the result inside.
So regarding functions synchronization you are good it is more a matter of scope.
This example should work :
const function1 = () => {
const function2 = () => {
return 'something'
}
return function2
}
Your wrote
const function1 = () => {
const function2 = () => {
return 'something'
}
//nothing returned for function1
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论