Reputation: 107
I am trying to insert data in MySQL using Knex inside the loop first, and then want to get the data. But, getting the data executes first before the insertion. May someone please help me in doing this?
for (let i = 0; i < fileArray.length; i++) {
fileLocation = fileArray[i].location;
imgLocationArray.push(fileLocation);
knex("files")
.insert({
fileLink: fileLocation,
todoId: todoId,
userId: userId
})
.then(() => {
console.log("phle chala!");
})
.catch(err => console.log(err));
}
knex("files")
.where("files.userId", userId)
.then(userFiles => {
console.log("baad wala hai yrr");
res.json({
userFiles: userFiles
});
})
.catch(err => console.log(err));
Upvotes: 1
Views: 141
Reputation: 7654
When using promises (as Knex queries do) JavaScript will continue straight onto the next statement without waiting for the previous one to finish. This is what you're encountering here: your code starts all the database inserts, but does not wait for them to finish before issuing the query to get back the data.
Because you're iterating over a series of files, Promise.all
is an ideal candidate for a solution. Here's how it works. First, we collect up all the promises:
const insertions = fileArray.map(file => {
fileLocation = fileArray[i].location;
imgLocationArray.push(fileLocation);
return knex("files")
.insert({
fileLink: fileLocation,
todoId: todoId,
userId: userId
})
})
Note the return
statement here, that's very important. Next, we wait for all those promises to finish:
Promise.all(insertions)
.then(() => knex("files").where("files.userId", userId))
.then(userFiles => {
console.log("baad wala hai yrr");
res.json({
userFiles: userFiles
});
})
.catch(err => console.log(err));
Only in this final .then
block can we depend on the data being available to us, because all the previous queries have finished.
If you happen to be working in an environment on your server where async
/await
is available (Node versions after 7.6) then you can do this:
try {
await Promise.all(insertions);
const userFiles = await knex("files").where("files.userId", userId);
res.json({ userFiles });
} catch (e) {
// Handle database error
}
Many people find this syntax more readable. Note that the function containing this code must be declared with the async
keyword:
myExpressRouter.post("userfiles", async (req, res) => {
// ...
})
Upvotes: 2