Quote:
Originally Posted by microbet
I made a couple passes at async, await, but not in earnest. I want to understand it the "old fashioned" way first. I didn't really want to use multer or anything like it, but apparently fileupload was taken out/deprecated from express and you have to use something third party. I don't quite get the role of 'cb' in there. I don't know if that's just because I don't get it or because it's obscured in multer.
Code:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../solarreact/public/img')
},
filename: function (req, file, cb) {
fs.readFile('../solarreact/src/ImageData.json', 'utf8', (err, data) => {
if (err) throw err;
imgDataArr = JSON.parse(data);
const filename = imgDataArr[imgDataArr.length-1][2].toString() + '_' + imgDataArr[imgDataArr.length-1][0].toString() + '.jpg';
imgDataArr.push([imgDataArr.length+1, "./img/" + filename, imgDataArr[imgDataArr.length-1][2], "this would be the caption here"]);
console.log(JSON.stringify(imgDataArr));
writeImageData(imgDataArr);
cb(null, filename);
});
}
});
var upload = multer({
storage: storage
});
app.post('/api/imgupload', upload.single('image'), function(req, res, next) {
res.send('this is post route upload');
});
Code:
function writeImageData(jsondata) {
fs.writeFile('../solarreact/src/ImageData.json', JSON.stringify(jsondata), (err) => {
if (err) throw err;
console.log('the file has been written');
});
}
edit: added the last function there
This looks ok except throw err might not going to break the flow the way you expect - since you're in asynchronous land. You probably need to pass err as the first argument to cb(err, data) instead. This will probably call the express next(error) behind the scenes, which is the equivalent of throwing an error in the express asynchronous flow. Does the multer example use throw?
Same goes for writeImageData. You're firing this off as an async process while the primary request/response flow continues on. So any errors won't be handled at all - they just get thrown to the node event loop executor, which has no idea what to do with them. If you want the user to get some input if the file write fails, you'll have to use another callback here and only call cb() inside that. Or use async/await (or straight promises, or the 3rd party async-js lib). You're probably getting an idea what "callback hell" means at this point.
The cb() is basically a nested callback inside filename()/fsReadData(). Whatever function inside multer (obscured but you could look at the code) that executes filename() is feeding a callback (cb()) which it uses to do the actual work. fs.readData takes an anonymous function as a callback ((err, data) => ... ) which gets executed when it's done and that ultimately executes the parent callback (cb) at the end.
Also holy 8-space tabs. Muh horizontal space!
I'll play with this some more when I get into work.
One of the best things about pull requests is multiple users can comment right on the lines of code in question - makes collaboration super easy.