Hi guys sorry for the noob question but I was trying to upload file from angular js using https://github.com/danialfarid/ng-file-upload. The problem is when I multer the req.body will always empty. Is this normal? if this is normal how could I send file with some data to name it like [data.id].[mimetype] Something like this
Thank you for your patience in reading my issue here is my Request Payload and code on server side
Request Payload
------WebKitFormBoundarykUG7UcxeBDOSFFb1
Content-Disposition: form-data; name="file"; filename="AD ShoppingisGREATedit.jpg"
Content-Type: image/jpeg
------WebKitFormBoundarykUG7UcxeBDOSFFb1
Content-Disposition: form-data; name="email"
[email protected]
------WebKitFormBoundarykUG7UcxeBDOSFFb1
Content-Disposition: form-data; name="classId"
76
------WebKitFormBoundarykUG7UcxeBDOSFFb1--
At my Server side
router.post('/upload', function(req, res, next){
console.log('uploading---')
console.log(req)
var storage = multer.diskStorage({
destination: function (req, file, cb) {
console.log(req.body)
cb(null, ('hidden/images/slip/' +req.body.classId) )
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
//var upload = multer({ dest: ('hidden/images/slip/' + req.body.classId) }).single('file')
var upload = multer({ storage:storage }).single('file')
console.log(upload)
upload(req,res,function(err) {
if(err) {
return handleError(err, res);
}
console.log("done upload---")
res.json({"status":"completed"});
});
})
From the documentation:
Note that
req.bodymight not have been fully populated yet. It depends on the order that the client transmits fields and files to the server.
As you can see in your request payload, the file is sent before the classId field, and thus there is no way for multer to know about classId when it's handling the file.
I wish I had an easy solution for you but the only thing I can recommend is to manually reorder the fields with javascript to make sure that fields are sent before files.
This has come up a number of times before, e.g. #146 where the workaround is outlined...
Oh Thank you it's work!!!. I think may be I should contribute in https://github.com/danialfarid/ng-file-upload about re-order field so this should not be problem thank you for your help and quick respond
That would be awesome :raised_hands:
@LinusU How to use metadata in multer? I used gridfs-storage-engine. It used req.body pass metadata.
It doesn't work for me. but i found the real cause is, we should print req.body inside the upload() function, instead of outside of it (either before or after it).
Try adding below line
console.log(req.body)
near console.log("done upload---") in above code example, it should print all non-file type form fields .
@LinusU Thank you very much!!! My uploading process was based on field in form that was next to input type='file' and I didn't got it in req.body. Thank you very much!
Thanks @LinusU it works for me too.
how about this ?
front end :
$commentForm.on('submit', function(e) {
// on add new comment
e.stopPropagation(); // Stop stuff happening
e.preventDefault(); // Totally stop stuff happening
var id = $(this).attr('id');
// Create a form-data object and add the files
var form_data_images = new FormData();
form_data_images.append('shareId', id);
form_data_images.append('userId', userLocal);
// grabbing all the input fields for the images :
var files_inputs = $("form#" + id + ".commentForm").find("input[type=file]");
// getting the images from all of the input fields :
$.each(files_inputs, function(key, value)
{
var className = $(this).get(0).className;
console.log('className :', className )
// images :
if(className == "image-comment"){
var image = $(this).get(0).files[0];
form_data_images.append('comment-image', image);
console.log('image :',image )
}
});
// AJAX call (images):
$.ajax({
url: '/users/feeds/uploadCommentsImages/',
type: 'POST',
method: 'POST',
dataType: 'json',
data: form_data_images,
success: function (data) {
console.log('from success and data: ', data)
},
error : function (err) {
console.log(err)
},
cache: false,
contentType: false,
processData: false
});
});
back end :
router.post('/uploadCommentsImages/', function (req, res, next) {
// console.log('form :' , form);
// console.log('request.body :' , req.body);
// console.log('request ' , req);
let shareId = "";
let userId = "";
// multer storage (comments images uploads)
var commentsImagesStorage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, path.join(__dirname, './../uploads/comments/images'));
},
filename: function(req, file, cb) {
// accessing req body :
var test = req.body;
console.log('test', test)
shareId = req.body.shareId;
userId = req.body.userId;
cb(null, file.fieldname + '-' + shareId + '-'+ userId + '-' + Date.now() + path.extname(file.originalname));
}
});
// multer file filter (comments images uploads)
var fileFilterCommentsImages = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
// accept a avatar
cb(null, true);
} else {
// reject an avatar
cb(null, false);
}
}
// multer constraints (comments images uploads) and chain the uplaoding of the array
var upload = multer({
storage:commentsImagesStorage,
limits:{
fileSize: 1024 * 1024 * 5 },
fileFilter : fileFilterCommentsImages
}).array('comment-image');
upload(req,res,function(err) {
if(err) {
return handleError(err, res);
}
console.log("done")
res.status(200).json({msg : "files received", files: req.files, shareId : req.body.shareId, userId : req.body.userId})
});
});
in the variable test I have access to inputs passed in from the front
From the documentation:
Note that
req.bodymight not have been fully populated yet. It depends on the order that the client transmits fields and files to the server.As you can see in your request payload, the file is sent before the
classIdfield, and thus there is no way for multer to know aboutclassIdwhen it's handling the file.I wish I had an easy solution for you but the only thing I can recommend is to manually reorder the fields with javascript to make sure that fields are sent before files.
This has come up a number of times before, e.g. #146 where the workaround is outlined...
Save my life thanks :)
@LinusU thanks. save my day ! 馃拑
still facing this issue i don't know when this issue will be fixed
Most helpful comment
From the documentation:
As you can see in your request payload, the file is sent before the
classIdfield, and thus there is no way for multer to know aboutclassIdwhen it's handling the file.I wish I had an easy solution for you but the only thing I can recommend is to manually reorder the fields with javascript to make sure that fields are sent before files.
This has come up a number of times before, e.g. #146 where the workaround is outlined...