Multer: unable to send multiple files using node, getting Error: unexpected field

Created on 14 Jan 2016  路  17Comments  路  Source: expressjs/multer

I am using Angular ng-file-upload to upload files. When sending here is the html, but I am getting error 'Error: Unexpected field' and from the client getting Internal Error 500. Can you please assist with this issue?

<div class="button btn btn-danger" ngf-select ng-model="files" name="files" ngf-multiple="true">Select</div>
  <button type="submit" ng-click="submit()">submit</button>

Angular as follows

if($scope.files){
        console.log('upload multiple works');
        console.log($scope.files);
        $scope.uploadFiles($scope.files);
      }
    };

$scope.uploadFiles = function (files) {
      if (files && files.length) {
        for (var i = 0; i < files.length; i++) {
          Upload.upload({
            url: 'api/admin/photos',
            data: {file: files}
          }).then(function(resp){
            console.log('Successfully ' + resp.config.data.file.name);
            $scope.myPic = resp.config.data.file.name;
          },
          function(resp){
            console.log('Error status: ' + resp.status);
          },
          function(evt){
            var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
             console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
          })
          }
        }

      };

and using node

var storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'public/img')
  },
  filename: function (req, file, cb) {
    //cb(null, file.originalname + '-' + Date.now())
    cb(null, file.originalname )
  }
});

var upload = multer({ storage: storage });

//upload photos
apiRoutes.post('/admin/photos',upload.array('files'),function(req,res){

    console.log(req);


    //save to database



    console.log(req);
     console.log(req.file.originalname);
    console.log(req.file.originalname);
     res.json(req.file[0]);

});

Most helpful comment

Change your code.
from :

Upload.upload({
            url: 'api/admin/photos',
            data: {file: files}
 })

to:

Upload.upload({
            url: 'api/admin/photos',
            arrayKey: '',
            data: {file: files}
          })

It should work.

All 17 comments

The field is named file in the browser: data: {file: files}. But it's named files on the server: upload.array('files'). Change them to match up.

Also, since you are receiving multiple files (upload.array(...)) you should look at req.files instead of req.file.

I've made the changes to data: {files: files} and I also did something with the errors...

app.use(function (err, req, res, next) {
  console.log(err) 
  console.log(err.stack)
})

I got the following error while doing this.

{ [Error: Unexpected field]
code: 'LIMIT_UNEXPECTED_FILE',
 field: 'files[0]',
 storageErrors: [] }

No luck so far.

i got same issue in ng-file-upload

The problem is that the clients you are using are appending [n] to the field names, which we currently don't handle...

@LinusU its that bug of ng-file-upload?

Well, it's hard to say. As far as I know, there isn't any specification saying how you _should_ name the fields. I think that they are compatible with how it works in php.

It would certainly be good if it where configurable though, I would file an issue to them about that.

Change your code.
from :

Upload.upload({
            url: 'api/admin/photos',
            data: {file: files}
 })

to:

Upload.upload({
            url: 'api/admin/photos',
            arrayKey: '',
            data: {file: files}
          })

It should work.

Thank you @shivam1401 for that solution 馃憤

Thanks a lot @shivam1401! Finally it works for me! 馃憤

@shivam1401 Hi, can you explain why should add this 'arrayKey' field?

Thanks @shivam1401!

The reason for the error is that multer currently does not support the array syntax that ng-file-upload uses by default which is files[0], files[1], files[2], etc. multer is expecting a series of files with the same field name.

The easiest solution is to set ng-file-upload's arrayKey option like so to avoid appending the [index] part

@shivam1401 genius!

@usos0k @leoparis89 @xitman78 @LinusU : Happy To Help guys..

arrayKey: '', solves the error Unexpected Field
But it leads to another problem
I am trying to send json object along with multiple files
JSON object
{
name: xyz,
data : [
{ k1: v1, k2: v2 },
{ k1: v3, k2: v4 }
]
}

But on server side it is received as
{
name: xyz,
data : {
k1: [v1, v3], k2: [v2, v4]
}
}

If I remove arrayKey, correct JSON object received at server

Just use any() instead of array('file').

When using array('file'), multer throws error because it expects all fields to be named file, while ng-file-upload names them file[0], file[1], etc..
I wouldn't recommend using arrayKey: '' because it's basically a hack, and messes up serialization of other arrays if you are sending additional data.

Another option is to use files(), and do something like:

upload.files([
    { name: 'file[0]', maxCount: 1 },
    { name: 'file[1]', maxCount: 1 },
    ...
])

But then req.files is object with arrays of files.

Thanks guys

Was this page helpful?
0 / 5 - 0 ratings

Related issues

BlueOctober picture BlueOctober  路  3Comments

nickretallack picture nickretallack  路  4Comments

adrienbarreau picture adrienbarreau  路  3Comments

thammarith picture thammarith  路  3Comments

ChristianRich picture ChristianRich  路  4Comments