Dan Dan - 3 months ago 14
AngularJS Question

File submission from an Angular app to an Express Web Server

I am trying to pass a File between my HTML form and a running Express Web Server with Angular. If I remove Angular from the equation and submit the form with a normal POST, Express receives the file.

My form:

<form ng-submit="addEntry()" enctype="multipart/form-data">
<fieldset>
<legend>Upload Image</legend>
<div class="form-group">
<label>
mmol/L:
<input type="number" ng-model="mmol">
</label>
</div>
<div class="form-group">
<label>
Carbs:
<input type="number" ng-model="carbs">
</label>
</div>
<div class="form-group">
<label>
Image:
<input type="file" name="file" file-upload file-changed="setFile(file)">
</label>
</div>
<div class="form-group">
<button type="submit">Submit</button>
</div>
</fieldset>




My fileUpload directive:

app.directive('fileUpload', function() {
return {
scope: {
fileChanged: '&'
},
link: function(scope, elem, attrs) {
elem.bind('change', function(event) {
scope.fileChanged({
file: event.target.files[0]
});
});
}
}
});


My Controller:

$scope.addEntry = function() {
APIFactory.addEntry($scope.mmol, $scope.carbs, $scope.file);
}


APIFactory:

app.factory('APIFactory', ['$http', function($http) {
return {
addEntry: function(mmol, carbs, file) {
var reading = {
mmol: mmol,
carbs: carbs,
file: file
};
console.log(reading);
$http({
method: 'POST',
url: 'http://localhost:1337/upload',
data: reading
}).then(function success(response) {
console.log(response);
}, function error(err) {
console.log(err);
})
}
}

}]);


Express Server:

app.post('/upload', upload.single('image'), function(req, res) {
var image = req.file;

console.log(image);
});


The result of console.log(reading) in APIFactory:

Object {mmol: 10, carbs: 10, file: File}


The result of console.log(image) in my Express Server:

undefined


Within the Client side of the application, the File object gets passed around. The problem arises when I try to pass it to my server. Is anyone able to provide any insight into why this is happening?

Dan Dan
Answer

I found a solution with the help of FormData

app.factory('APIFactory', ['$http', function($http) {
  return {
    addEntry: function(mmol, carbs, file) {
      var fd = new FormData();
      fd.append('mmol', mmol);
      fd.append('carbs', carbs);
      fd.append('file', file);

      $http({
        method: 'POST',
        url: 'http://localhost:1337/upload',
        data: fd,
        transformRequest: angular.identity,
        headers: {'Content-Type': undefined}
      }).then(function success(response) {
        console.log(response);
      }, function error(err) {
        console.log(err);
      })
    }
  }
}]);

I also edited my Express server to tell multer to look for a single file with the key file.

app.post('/upload', upload.single('file'), function(req, res) {
  // Code omitted
});

And now I receive my file in the following format:

{ fieldname: 'file',
  originalname: 'placeholder.png',
  encoding: '7bit',
  mimetype: 'image/png',
  buffer: <Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 00 fa 00 00 00 fa 08 06 00 00 00 88 ec 5a 3d 00 00 0a 41 69 43 43 50 49 43 43 20 50 72 6f 66 69 ... >,
  size: 6022 }