Nodejs async-waterfall callback function is not defined
up vote
0
down vote
favorite
I am trying to save the file and details of it in the database.
Waterfall function with two calls but the second function is not waiting for the first function to finish.
Even without using waterfall eachseries doesn't work as expected. It doesn't wait for the record to be created and hence uniqueness error occurs due to same id.
What am I doing wrong here and how can I fix it?
Thanks!
async.eachSeries(uploadedPhotos, async function (uploadedFile, callback) {
async.waterfall([
async function() {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate({ customer_no: req.session.userId, file_type: 'profile_image' }, {
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).exec(async (err, user, wasCreated) => {
if (err) { return res.serverError(err); }
if (wasCreated) {
// created a new user
sails.log("new file was uploaded...")
return cbb(err, "done");
// return res.send("sent");
}
else {
// found existing user
var user = await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).intercept(err => {
// Return a modified error here (or a special exit signal)
// and .create() will throw that instead
err.message = "Uh oh: " + err.message;
return err;
}).fetch();
if (user) {
sails.log("found existing files..")
return cbb(err, "done");
}
sails.log("this should not be called");
}
});
}
], (err, success) => {
if (err) sails.log(err);
return callback(err, 'done')
});
}, function (err) {
// if any of the saves produced an error, err would equal that error
if (err) {
sails.log(err);
} else {
return res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
javascript node.js asynchronous waterfall
add a comment |
up vote
0
down vote
favorite
I am trying to save the file and details of it in the database.
Waterfall function with two calls but the second function is not waiting for the first function to finish.
Even without using waterfall eachseries doesn't work as expected. It doesn't wait for the record to be created and hence uniqueness error occurs due to same id.
What am I doing wrong here and how can I fix it?
Thanks!
async.eachSeries(uploadedPhotos, async function (uploadedFile, callback) {
async.waterfall([
async function() {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate({ customer_no: req.session.userId, file_type: 'profile_image' }, {
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).exec(async (err, user, wasCreated) => {
if (err) { return res.serverError(err); }
if (wasCreated) {
// created a new user
sails.log("new file was uploaded...")
return cbb(err, "done");
// return res.send("sent");
}
else {
// found existing user
var user = await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).intercept(err => {
// Return a modified error here (or a special exit signal)
// and .create() will throw that instead
err.message = "Uh oh: " + err.message;
return err;
}).fetch();
if (user) {
sails.log("found existing files..")
return cbb(err, "done");
}
sails.log("this should not be called");
}
});
}
], (err, success) => {
if (err) sails.log(err);
return callback(err, 'done')
});
}, function (err) {
// if any of the saves produced an error, err would equal that error
if (err) {
sails.log(err);
} else {
return res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
javascript node.js asynchronous waterfall
1
So Node asycnjs library and theasync/await
keywords are two very different things. The two do not intermix as you are attempting here. Also doingconst async = require('async')
as you would have done earlier actually overwrites the usage of theasync
keyword in further use. If you must use the library ( you really don't need to now ), then instead doconst Async = require('async')
so at least there is a case difference between the two terms. But even then you cannot mark callback functions asasync
.
– Neil Lunn
3 hours ago
1
Basicallypromise.then(res => newpromise(res)).then(...)
is basically what a "waterfall" is. Orvar res1 = await promise; var2 = await promise2(res1)
is theasync/await
version of waterfall. So the two patterns really are mutually exclusive.
– Neil Lunn
3 hours ago
@NeilLunn I haven't overridden async. I am using sails.js framework here.
– Tech Team
3 hours ago
Yes you have overridden it.async.waterfall
andasync function()
both use the lowercaseasync
, which I'm pointing out is a "keyword". I'm also outright "showing you" why you don't need this, and that you simply appear to be copying an approach from an older source you found online way back when usage of "async js" was a popular thing. As in, a couple of years ago now. It's pretty much redundant if your nodejs supports async/await, or even promises in general.
– Neil Lunn
3 hours ago
@NeilLunn Okay. I understand that I don't need waterfall but that still doesn't allow me to loop through the files using eachseries as it shows uniqueness error.
– Tech Team
2 hours ago
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I am trying to save the file and details of it in the database.
Waterfall function with two calls but the second function is not waiting for the first function to finish.
Even without using waterfall eachseries doesn't work as expected. It doesn't wait for the record to be created and hence uniqueness error occurs due to same id.
What am I doing wrong here and how can I fix it?
Thanks!
async.eachSeries(uploadedPhotos, async function (uploadedFile, callback) {
async.waterfall([
async function() {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate({ customer_no: req.session.userId, file_type: 'profile_image' }, {
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).exec(async (err, user, wasCreated) => {
if (err) { return res.serverError(err); }
if (wasCreated) {
// created a new user
sails.log("new file was uploaded...")
return cbb(err, "done");
// return res.send("sent");
}
else {
// found existing user
var user = await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).intercept(err => {
// Return a modified error here (or a special exit signal)
// and .create() will throw that instead
err.message = "Uh oh: " + err.message;
return err;
}).fetch();
if (user) {
sails.log("found existing files..")
return cbb(err, "done");
}
sails.log("this should not be called");
}
});
}
], (err, success) => {
if (err) sails.log(err);
return callback(err, 'done')
});
}, function (err) {
// if any of the saves produced an error, err would equal that error
if (err) {
sails.log(err);
} else {
return res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
javascript node.js asynchronous waterfall
I am trying to save the file and details of it in the database.
Waterfall function with two calls but the second function is not waiting for the first function to finish.
Even without using waterfall eachseries doesn't work as expected. It doesn't wait for the record to be created and hence uniqueness error occurs due to same id.
What am I doing wrong here and how can I fix it?
Thanks!
async.eachSeries(uploadedPhotos, async function (uploadedFile, callback) {
async.waterfall([
async function() {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate({ customer_no: req.session.userId, file_type: 'profile_image' }, {
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).exec(async (err, user, wasCreated) => {
if (err) { return res.serverError(err); }
if (wasCreated) {
// created a new user
sails.log("new file was uploaded...")
return cbb(err, "done");
// return res.send("sent");
}
else {
// found existing user
var user = await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}).intercept(err => {
// Return a modified error here (or a special exit signal)
// and .create() will throw that instead
err.message = "Uh oh: " + err.message;
return err;
}).fetch();
if (user) {
sails.log("found existing files..")
return cbb(err, "done");
}
sails.log("this should not be called");
}
});
}
], (err, success) => {
if (err) sails.log(err);
return callback(err, 'done')
});
}, function (err) {
// if any of the saves produced an error, err would equal that error
if (err) {
sails.log(err);
} else {
return res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
javascript node.js asynchronous waterfall
javascript node.js asynchronous waterfall
asked 3 hours ago
Tech Team
427
427
1
So Node asycnjs library and theasync/await
keywords are two very different things. The two do not intermix as you are attempting here. Also doingconst async = require('async')
as you would have done earlier actually overwrites the usage of theasync
keyword in further use. If you must use the library ( you really don't need to now ), then instead doconst Async = require('async')
so at least there is a case difference between the two terms. But even then you cannot mark callback functions asasync
.
– Neil Lunn
3 hours ago
1
Basicallypromise.then(res => newpromise(res)).then(...)
is basically what a "waterfall" is. Orvar res1 = await promise; var2 = await promise2(res1)
is theasync/await
version of waterfall. So the two patterns really are mutually exclusive.
– Neil Lunn
3 hours ago
@NeilLunn I haven't overridden async. I am using sails.js framework here.
– Tech Team
3 hours ago
Yes you have overridden it.async.waterfall
andasync function()
both use the lowercaseasync
, which I'm pointing out is a "keyword". I'm also outright "showing you" why you don't need this, and that you simply appear to be copying an approach from an older source you found online way back when usage of "async js" was a popular thing. As in, a couple of years ago now. It's pretty much redundant if your nodejs supports async/await, or even promises in general.
– Neil Lunn
3 hours ago
@NeilLunn Okay. I understand that I don't need waterfall but that still doesn't allow me to loop through the files using eachseries as it shows uniqueness error.
– Tech Team
2 hours ago
add a comment |
1
So Node asycnjs library and theasync/await
keywords are two very different things. The two do not intermix as you are attempting here. Also doingconst async = require('async')
as you would have done earlier actually overwrites the usage of theasync
keyword in further use. If you must use the library ( you really don't need to now ), then instead doconst Async = require('async')
so at least there is a case difference between the two terms. But even then you cannot mark callback functions asasync
.
– Neil Lunn
3 hours ago
1
Basicallypromise.then(res => newpromise(res)).then(...)
is basically what a "waterfall" is. Orvar res1 = await promise; var2 = await promise2(res1)
is theasync/await
version of waterfall. So the two patterns really are mutually exclusive.
– Neil Lunn
3 hours ago
@NeilLunn I haven't overridden async. I am using sails.js framework here.
– Tech Team
3 hours ago
Yes you have overridden it.async.waterfall
andasync function()
both use the lowercaseasync
, which I'm pointing out is a "keyword". I'm also outright "showing you" why you don't need this, and that you simply appear to be copying an approach from an older source you found online way back when usage of "async js" was a popular thing. As in, a couple of years ago now. It's pretty much redundant if your nodejs supports async/await, or even promises in general.
– Neil Lunn
3 hours ago
@NeilLunn Okay. I understand that I don't need waterfall but that still doesn't allow me to loop through the files using eachseries as it shows uniqueness error.
– Tech Team
2 hours ago
1
1
So Node asycnjs library and the
async/await
keywords are two very different things. The two do not intermix as you are attempting here. Also doing const async = require('async')
as you would have done earlier actually overwrites the usage of the async
keyword in further use. If you must use the library ( you really don't need to now ), then instead do const Async = require('async')
so at least there is a case difference between the two terms. But even then you cannot mark callback functions as async
.– Neil Lunn
3 hours ago
So Node asycnjs library and the
async/await
keywords are two very different things. The two do not intermix as you are attempting here. Also doing const async = require('async')
as you would have done earlier actually overwrites the usage of the async
keyword in further use. If you must use the library ( you really don't need to now ), then instead do const Async = require('async')
so at least there is a case difference between the two terms. But even then you cannot mark callback functions as async
.– Neil Lunn
3 hours ago
1
1
Basically
promise.then(res => newpromise(res)).then(...)
is basically what a "waterfall" is. Or var res1 = await promise; var2 = await promise2(res1)
is the async/await
version of waterfall. So the two patterns really are mutually exclusive.– Neil Lunn
3 hours ago
Basically
promise.then(res => newpromise(res)).then(...)
is basically what a "waterfall" is. Or var res1 = await promise; var2 = await promise2(res1)
is the async/await
version of waterfall. So the two patterns really are mutually exclusive.– Neil Lunn
3 hours ago
@NeilLunn I haven't overridden async. I am using sails.js framework here.
– Tech Team
3 hours ago
@NeilLunn I haven't overridden async. I am using sails.js framework here.
– Tech Team
3 hours ago
Yes you have overridden it.
async.waterfall
and async function()
both use the lowercase async
, which I'm pointing out is a "keyword". I'm also outright "showing you" why you don't need this, and that you simply appear to be copying an approach from an older source you found online way back when usage of "async js" was a popular thing. As in, a couple of years ago now. It's pretty much redundant if your nodejs supports async/await, or even promises in general.– Neil Lunn
3 hours ago
Yes you have overridden it.
async.waterfall
and async function()
both use the lowercase async
, which I'm pointing out is a "keyword". I'm also outright "showing you" why you don't need this, and that you simply appear to be copying an approach from an older source you found online way back when usage of "async js" was a popular thing. As in, a couple of years ago now. It's pretty much redundant if your nodejs supports async/await, or even promises in general.– Neil Lunn
3 hours ago
@NeilLunn Okay. I understand that I don't need waterfall but that still doesn't allow me to loop through the files using eachseries as it shows uniqueness error.
– Tech Team
2 hours ago
@NeilLunn Okay. I understand that I don't need waterfall but that still doesn't allow me to loop through the files using eachseries as it shows uniqueness error.
– Tech Team
2 hours ago
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Updated answer:
I rewrite the code.
I forgot that async.js handles promise in different way. Basically, you don't use callback()
. Use return
instead. If an error occurs, use throw new Error(message)
.
See here for more information. Read topic: Using ES2017 async functions.
async.eachSeries(uploadedPhotos, async uploadedFile => {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
var fileID = lastUser[0].id;
fileID += 1;
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate(
{ customer_no: req.session.userId, file_type: 'profile_image' },
{
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}
).exec(async (err, user, wasCreated) => {
if (err) throw new Error(err);
if (wasCreated) {
sails.log("new file was uploaded...");
return;
} else {
await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
})
.intercept(err => {
throw new Error("Uh oh: " + err.message);
}).fetch();
if (user) {
sails.log("found existing files..");
return;
} else {
sails.log("this should not be called");
return;
}
}
});
}, err => {
// Don't call res.serverError() or res.json() inside the async loop!
if (err) {
sails.log(err);
res.serverError(err);
}
else {
res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
I think the first problem here is that the you forget to give the first task a callback function(cbb in this case).
async.waterfall([
async function(cbb) {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
...
Secondly, you shouldn't return a callback. Callback is a function not a promise. Just use them normally.
By the way, const async = require('async');
will NOT override async
keyword. Compiler can tell the difference between them. This is proved by the following script example:
const async = require('async');
let runPromise = (name, timer, success = true) => {
console.log(`${name} starts.`);
return new Promise((resolve, reject) => {
if (success) {
setTimeout(function () {
resolve(`${name} finished after ${timer / 1000} seconds(resolved).`);
}, timer);
} else {
reject(`${name} failed(rejected).`);
}
});
};
async function asyncFunction() {
let txt = await runPromise('A', 1000);
console.log(txt);
}
asyncFunction();
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Updated answer:
I rewrite the code.
I forgot that async.js handles promise in different way. Basically, you don't use callback()
. Use return
instead. If an error occurs, use throw new Error(message)
.
See here for more information. Read topic: Using ES2017 async functions.
async.eachSeries(uploadedPhotos, async uploadedFile => {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
var fileID = lastUser[0].id;
fileID += 1;
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate(
{ customer_no: req.session.userId, file_type: 'profile_image' },
{
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}
).exec(async (err, user, wasCreated) => {
if (err) throw new Error(err);
if (wasCreated) {
sails.log("new file was uploaded...");
return;
} else {
await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
})
.intercept(err => {
throw new Error("Uh oh: " + err.message);
}).fetch();
if (user) {
sails.log("found existing files..");
return;
} else {
sails.log("this should not be called");
return;
}
}
});
}, err => {
// Don't call res.serverError() or res.json() inside the async loop!
if (err) {
sails.log(err);
res.serverError(err);
}
else {
res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
I think the first problem here is that the you forget to give the first task a callback function(cbb in this case).
async.waterfall([
async function(cbb) {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
...
Secondly, you shouldn't return a callback. Callback is a function not a promise. Just use them normally.
By the way, const async = require('async');
will NOT override async
keyword. Compiler can tell the difference between them. This is proved by the following script example:
const async = require('async');
let runPromise = (name, timer, success = true) => {
console.log(`${name} starts.`);
return new Promise((resolve, reject) => {
if (success) {
setTimeout(function () {
resolve(`${name} finished after ${timer / 1000} seconds(resolved).`);
}, timer);
} else {
reject(`${name} failed(rejected).`);
}
});
};
async function asyncFunction() {
let txt = await runPromise('A', 1000);
console.log(txt);
}
asyncFunction();
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
add a comment |
up vote
0
down vote
Updated answer:
I rewrite the code.
I forgot that async.js handles promise in different way. Basically, you don't use callback()
. Use return
instead. If an error occurs, use throw new Error(message)
.
See here for more information. Read topic: Using ES2017 async functions.
async.eachSeries(uploadedPhotos, async uploadedFile => {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
var fileID = lastUser[0].id;
fileID += 1;
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate(
{ customer_no: req.session.userId, file_type: 'profile_image' },
{
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}
).exec(async (err, user, wasCreated) => {
if (err) throw new Error(err);
if (wasCreated) {
sails.log("new file was uploaded...");
return;
} else {
await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
})
.intercept(err => {
throw new Error("Uh oh: " + err.message);
}).fetch();
if (user) {
sails.log("found existing files..");
return;
} else {
sails.log("this should not be called");
return;
}
}
});
}, err => {
// Don't call res.serverError() or res.json() inside the async loop!
if (err) {
sails.log(err);
res.serverError(err);
}
else {
res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
I think the first problem here is that the you forget to give the first task a callback function(cbb in this case).
async.waterfall([
async function(cbb) {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
...
Secondly, you shouldn't return a callback. Callback is a function not a promise. Just use them normally.
By the way, const async = require('async');
will NOT override async
keyword. Compiler can tell the difference between them. This is proved by the following script example:
const async = require('async');
let runPromise = (name, timer, success = true) => {
console.log(`${name} starts.`);
return new Promise((resolve, reject) => {
if (success) {
setTimeout(function () {
resolve(`${name} finished after ${timer / 1000} seconds(resolved).`);
}, timer);
} else {
reject(`${name} failed(rejected).`);
}
});
};
async function asyncFunction() {
let txt = await runPromise('A', 1000);
console.log(txt);
}
asyncFunction();
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
add a comment |
up vote
0
down vote
up vote
0
down vote
Updated answer:
I rewrite the code.
I forgot that async.js handles promise in different way. Basically, you don't use callback()
. Use return
instead. If an error occurs, use throw new Error(message)
.
See here for more information. Read topic: Using ES2017 async functions.
async.eachSeries(uploadedPhotos, async uploadedFile => {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
var fileID = lastUser[0].id;
fileID += 1;
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate(
{ customer_no: req.session.userId, file_type: 'profile_image' },
{
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}
).exec(async (err, user, wasCreated) => {
if (err) throw new Error(err);
if (wasCreated) {
sails.log("new file was uploaded...");
return;
} else {
await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
})
.intercept(err => {
throw new Error("Uh oh: " + err.message);
}).fetch();
if (user) {
sails.log("found existing files..");
return;
} else {
sails.log("this should not be called");
return;
}
}
});
}, err => {
// Don't call res.serverError() or res.json() inside the async loop!
if (err) {
sails.log(err);
res.serverError(err);
}
else {
res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
I think the first problem here is that the you forget to give the first task a callback function(cbb in this case).
async.waterfall([
async function(cbb) {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
...
Secondly, you shouldn't return a callback. Callback is a function not a promise. Just use them normally.
By the way, const async = require('async');
will NOT override async
keyword. Compiler can tell the difference between them. This is proved by the following script example:
const async = require('async');
let runPromise = (name, timer, success = true) => {
console.log(`${name} starts.`);
return new Promise((resolve, reject) => {
if (success) {
setTimeout(function () {
resolve(`${name} finished after ${timer / 1000} seconds(resolved).`);
}, timer);
} else {
reject(`${name} failed(rejected).`);
}
});
};
async function asyncFunction() {
let txt = await runPromise('A', 1000);
console.log(txt);
}
asyncFunction();
Updated answer:
I rewrite the code.
I forgot that async.js handles promise in different way. Basically, you don't use callback()
. Use return
instead. If an error occurs, use throw new Error(message)
.
See here for more information. Read topic: Using ES2017 async functions.
async.eachSeries(uploadedPhotos, async uploadedFile => {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
var fileID = lastUser[0].id;
fileID += 1;
sails.log("save file id is " + file_id);
sails.log("savee file id is " + uploadedFile['filename']);
var today = moment(new Date()).format('YYYY-MM-DD HH:mm:ss');
await TblUserFiles.findOrCreate(
{ customer_no: req.session.userId, file_type: 'profile_image' },
{
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile['filename'],
file_type: 'profile_image',
is_approved: 'No',
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
}
).exec(async (err, user, wasCreated) => {
if (err) throw new Error(err);
if (wasCreated) {
sails.log("new file was uploaded...");
return;
} else {
await TblUserFiles.create({
id: fileID,
customer_no: req.session.userId,
file_name: uploadedFile["filename"],
file_type: "image",
is_approved: "No",
approved_by: 0,
approved_on: today,
approved_from: ip,
uploaded_date: today,
modified_date: today
})
.intercept(err => {
throw new Error("Uh oh: " + err.message);
}).fetch();
if (user) {
sails.log("found existing files..");
return;
} else {
sails.log("this should not be called");
return;
}
}
});
}, err => {
// Don't call res.serverError() or res.json() inside the async loop!
if (err) {
sails.log(err);
res.serverError(err);
}
else {
res.json({
message: uploadedPhotos.length + ' file(s) uploaded successfully!',
files: uploadedPhotos
});
}
});
I think the first problem here is that the you forget to give the first task a callback function(cbb in this case).
async.waterfall([
async function(cbb) {
var lastUser = await TblUserFiles.find({}).sort('id DESC').limit(1);
// fileID remains undefined if i remove async-await from the function
var fileID = lastUser[0].id;
fileID += 1;
cbb(null, fileID, uploadedFile);
},
async function(file_id, uploadedFile, cbb) {
...
Secondly, you shouldn't return a callback. Callback is a function not a promise. Just use them normally.
By the way, const async = require('async');
will NOT override async
keyword. Compiler can tell the difference between them. This is proved by the following script example:
const async = require('async');
let runPromise = (name, timer, success = true) => {
console.log(`${name} starts.`);
return new Promise((resolve, reject) => {
if (success) {
setTimeout(function () {
resolve(`${name} finished after ${timer / 1000} seconds(resolved).`);
}, timer);
} else {
reject(`${name} failed(rejected).`);
}
});
};
async function asyncFunction() {
let txt = await runPromise('A', 1000);
console.log(txt);
}
asyncFunction();
edited 37 mins ago
answered 2 hours ago
Jonathan Tsai
463
463
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
add a comment |
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
I've added cbb and removed return from callbacks. But, still getting TypeError: cbb is not a function`
– Tech Team
1 hour ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
@TechTeam I updated the answer. I hope it works.
– Jonathan Tsai
35 mins ago
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53370636%2fnodejs-async-waterfall-callback-function-is-not-defined%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
So Node asycnjs library and the
async/await
keywords are two very different things. The two do not intermix as you are attempting here. Also doingconst async = require('async')
as you would have done earlier actually overwrites the usage of theasync
keyword in further use. If you must use the library ( you really don't need to now ), then instead doconst Async = require('async')
so at least there is a case difference between the two terms. But even then you cannot mark callback functions asasync
.– Neil Lunn
3 hours ago
1
Basically
promise.then(res => newpromise(res)).then(...)
is basically what a "waterfall" is. Orvar res1 = await promise; var2 = await promise2(res1)
is theasync/await
version of waterfall. So the two patterns really are mutually exclusive.– Neil Lunn
3 hours ago
@NeilLunn I haven't overridden async. I am using sails.js framework here.
– Tech Team
3 hours ago
Yes you have overridden it.
async.waterfall
andasync function()
both use the lowercaseasync
, which I'm pointing out is a "keyword". I'm also outright "showing you" why you don't need this, and that you simply appear to be copying an approach from an older source you found online way back when usage of "async js" was a popular thing. As in, a couple of years ago now. It's pretty much redundant if your nodejs supports async/await, or even promises in general.– Neil Lunn
3 hours ago
@NeilLunn Okay. I understand that I don't need waterfall but that still doesn't allow me to loop through the files using eachseries as it shows uniqueness error.
– Tech Team
2 hours ago