Tengo esto:
function afterCreateThePayment(req, res, rows) { for (var i = 0; i < rows.length; i++) { console.log(rows.length) var selecter = "SELECT * from SCHEDULE WHERE CLIENT_USERNAME = ? AND SESSION_STATUS = ?" //pass rows into this function mysqlconn.connect(function(err) { if (err) { console.error('Database connection failed: ' + err.stack); return; } mysqlconn.query(selecter, [rows[i]["USERNAME"], 'CONFIRMED'], async function(err, scheduleData) { if (err) { console.log(err); } for (var x = 0; x < scheduleData.length; x++) { console.log(scheduleData[x]) } // mysqlconn.end(); }) }) } } como puede ver, paso rows a esta función y luego trato de usar rows[i]["USERNAME"] como uno de los parámetros de consulta. Sin embargo, cuando hago esto, me sale el error
TypeError: Cannot read property 'USERNAME' of undefinedasí que no estoy seguro de qué hacer aquí, o si mi lógica es correcta. ¿alguien podría ayudar?
Su problema es que la variable de bucle i tiene como alcance afterCreateThePayment . Tenga en cuenta que var en javascript utiliza un alcance funcional, que es diferente al alcance de bloque con el que puede estar familiarizado en los lenguajes de estilo C.
Supongo que la devolución de llamada de mysqlconn.connect es asíncrona. Esto significa que el ciclo continúa ejecutándose, incrementando i . Para cuando ocurre la devolución de llamada, el bucle está fuera de los límites. Si observa el valor de i (no rows ) en su devolución de llamada, verá lo que sucedió.
Aquí hay un ejemplo similar:
for (var i = 0; i < 5; i++) { function internal() { console.log(i); } setTimeout(() => {internal();},1000); } La opción más simple es cambiar la var i en tu ciclo por let i . Hacer este cambio hará que el bloque i tenga alcance, de modo que el valor se aplicará solo a su llamada actual a mysqlconn.connect . En mi ejemplo, eso es simplemente:
for (let i = 0; i < 5; i++) { function internal() { console.log(i); } setTimeout(() => {internal();},1000); }