I've created following code, however i can't seem to figure out how to update the image if findOneAndUpdate
find result and beside that it seems like result.save
is being executed before put_form_url. How can i achieve such a function where if it exist it will update all properties and upload new image to s3 and if not it will create a new object with s3 upload.
router.post('/:id/:name/:birth/:country/:image', function(req, res, next) {
var params = req.params;
var accessHeader = req.headers;
process.env.AWS_ACCESS_KEY_ID=''
process.env.AWS_SECRET_ACCESS_KEY=''
AWS.config.region = 'eu-west-1';
var s3 = new AWS.S3();
User.findOneAndUpdate({"_id": params.id}, {$set:{"name": params.name, "birthday": params.birth, "country": params.country}}, {new: true}, function(error, result) {
if (!error) {
// If the document doesn't exist
if (!result) {
// Create it
put_from_url(params.image, new Date().toString, function(err, res) {
result = new User({
_id: params.id,
name: params.name,
birthday: new Date(params.birth),
country: params.country,
image: "url" + params.id
});
});
}
// Save the document
result.save(function(error) {
if (!error) {
res.json({ message: 'User created!' });
} else {
res.send(err);
}
});
}
});
});
Upload function
function put_from_url(url, key, callback) {
request({
url: url,
encoding: null
}, function(err, res, body) {
if (err)
return callback(err, res);
uploader.putObject({
Bucket: "",
Key: "/" + key,
ContentType: res.headers['content-type'],
ContentLength: res.headers['content-length'],
Body: body // buffer
}, callback);
})
}
Okay, it seems you have two parts of the question.
So in either case you have to store the image, so why not to do something like either first you update the image and then you update/insert the user or do the vice-versa. personally I would choose the former.
router.post('/:id/:name/:birth/:country/:image', function(req, res, next) {
var params = req.params;
var accessHeader = req.headers;
process.env.AWS_ACCESS_KEY_ID=''
process.env.AWS_SECRET_ACCESS_KEY=''
AWS.config.region = 'eu-west-1';
var s3 = new AWS.S3();
put_from_url(params.image, params.id, function(err, res) {
result = new User({
_id: params.id,
name: params.name,
birthday: new Date(params.birth),
country: params.country,
image: "url" + params.id
});
// Save the document
result.save(function(error) {
if (!error) {
res.json({ message: 'User created!' });
} else {
res.send(err);
}
});
});
few notes is that for key you were using date but I just used id so that it can be updated with new image later on. s3 object can be used and updated by unique key. if you want to do something like keep an old copy of images, you better use key like params.id/(new Date().toString)
so old images would not be overwritten
Secondly, save function inherently updates if the object is there based on _id else it creates a new one.
It surely will, javascript is inherently asynchronous which means if one code is taking too long, it will execute next statement. when you make a call to s3, its an I/O call which will try to upload an image to s3 and it will be handled, meanwhile your next line of code which in your case was result.save would be executed.
There are two ways. i> wrap the next call in the callback of previous call. and far better and superior ii> use promises.
Promises are sort of future event where you can tell upload to s3 then save into DB.
Promises have little learning curve, but it's great, clean and really helpful. q is one such promise module.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.