3

How to upload Files along with Form Data using Angularjs?

I am working on a UI that is built in AngularJs. It has a form where users put their details like Id, Name, Address, PIN etc. Along with that I have to provide a functionality where users can upload multiple files along with the FormData.

I have gone through the tutorials for File Upload in AngularJs and I've created a directive for uploading file.

The code in JavaScript looks like this,

var formData = new FormData();  
formData.append('id', $scope.id);
formData.append('name', $scope.name);
formData.append('addressLine1', $scope.addressLine1);
formData.append('addressLine2', $scope.addressLine2);
formData.append('road', $scope.road);
formData.append('city', $scope.city);
formData.append('pin', $scope.pin);
formData.append('state', $scope.state);
formData.append('country', $scope.country);
formData.append('file', $scope.file);

$http({
    method: 'POST',
    url: baseURL + "item/" + $scope.id,
    data: formData,
    responseType: 'arraybuffer',
    transformRequest: angular.identity,
    headers: {'Content-Type': undefined},
 });

In Spring MVC the controller looks like,

@RequestMapping(value = "item/{id}", method = RequestMethod.POST,
                consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public @ResponseBody ResponseResource addData(@PathVariable String id,
       @RequestParam DataRequestResource dataRequestResource,
       @RequestParam(value = "file") MultipartFile file){

DataRequestResource contains,

public class DataRequestResource {

    private String id;  
    private String name;
    private String addressLine1;    
    private String addressLine2;    
    private Long road;  
    private String city;    
    private String pin; 
    private String state;   
    private String country;

}

When I try to execute this I get

415 (Unsupported Media Type)

I can make this work using @RequestParam for each variable. But is there a way by which I can get the Form Data in Resource object and File in a separate parameter?

Community
  • 1
  • 1
  • Possible duplicate of [Angularjs how to upload multipart form data and a file?](https://stackoverflow.com/questions/24443246/angularjs-how-to-upload-multipart-form-data-and-a-file) – Vivz Aug 24 '17 at 11:01
  • The AngularJS code is correct if `$scope.file` is a [File object](https://developer.mozilla.org/en-US/docs/Web/API/File) from a [Filelist](https://developer.mozilla.org/en-US/docs/Web/API/FileList). What does the network tab of the Developer Console show for the payload? – georgeawg Aug 24 '17 at 17:41
  • *Note:* If `$scope.file` is a [Filelist](https://developer.mozilla.org/en-US/docs/Web/API/FileList), then append only `$scope.file[0]` to the [FormData object](https://developer.mozilla.org/en-US/docs/Web/API/FormData). – georgeawg Aug 24 '17 at 18:01
  • This answer might be helpful https://stackoverflow.com/questions/42671510/multipart-file-upload-using-angularjs-and-springmvc/42717177#42717177 – hrdkisback Aug 26 '17 at 09:34

1 Answers1

0
var data = new FormData();
for (var i = 0; i < files.length; i++) {
    data.append("Photo",files[i]);
}
data.append('description',description);

$http.post('/api/timeline/submit_post',data,{
    transformRequest: angular.identity,     
    headers: {'Content-Type': undefined}
}).then(function(response){
    var res = response.data;
     if(res.status == "Success"){
         $scope.$emit('hide_loader');
         $scope.$parent.posts = [];
         $scope.$parent.time = Date.now()/1000;
         $scope.$parent.getAllPostOfTimeline();
         toaster.pop('success', 'Post uploaded successfully.');   
         $scope.description = '';       
         $scope.modal.close();                
     }else{
         $scope.$emit('hide_loader');
         toaster.pop("error",res.msg);
     }
 },function(err){
     $scope.$emit('hide_loader');
     toaster.pop("error","Server");
 });
Alex M
  • 2,756
  • 7
  • 29
  • 35