File upload using Angular js and grails

2019-09-09 17:43发布

问题:

I am trying to implement a file upload using angular js and grails. I am able to call the grails controller method but not able to get the file from angular js using request.getFile() method. Here is my html code,

<script src="angular-file-upload-shim.min.js"></script> 
<script src="angular.min.js"></script>
<script src="angular-file-upload.min.js"></script> 

<div ng-controller="MyCtrl">
  <input type="text" ng-model="myModelObj">
  <input type="file" name="file" ng-file-select="onFileSelect($files)" >
  <div ng-file-drop="onFileSelect($files)" ng-file-drag-over-class="optional-css-class"
        ng-show="dropSupported">drop files here</div>
  <div ng-file-drop-available="dropSupported=true" 
        ng-show="!dropSupported">HTML5 Drop File is not supported!</div>
  <button ng-click="upload.abort()">Cancel Upload</button>
</div>

Here is the javascript code,

//inject angular file upload directives and service.
angular.module('myApp', ['angularFileUpload']);

var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
  $scope.onFileSelect = function($files) {
    //$files: an array of files selected, each file has name, size, and type.
    for (var i = 0; i < $files.length; i++) {
      var file = $files[i];
      $scope.upload = $upload.upload({
        url: 'GrailsApp/upload', //upload.php script, node.js route, or servlet url
        data: {myObj: $scope.myModelObj},
        file: file, // or list of files: $files for html5 only
      }).progress(function(evt) {
        console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
      }).success(function(data, status, headers, config) {
        // file is uploaded successfully
        console.log(data);
      });
    }
  };
}];

Here is the grails controller upload method,

def upload() {
    def f = request.getFile('file')
    if (f.empty) {
        flash.message = 'file cannot be empty'
        render(view: 'uploadForm')
        return
    }
f.transferTo(new File('D:/Filestorage/myfile.txt')) response.sendError(200, 'Done') }

While running this code gives a error like below,

Request.getFile() is applicable for argument types: (java.lang.String) values: {"file"}

But definitely it is going inside the controller method. Just not able to get the file from angular js.

But the same code works when I use a gsp form like below,

<g:uploadForm action="upload">
    <input type="file" name="file" />
    <input type="submit" />
</g:uploadForm>

The same code works like a chram and upload the file successfully.

回答1:

Docs say the fileName by default is file but add fileFormDataName: "myFile" explicitly as:

$scope.upload = $upload.upload({
    url: 'GrailsApp/upload', //upload.php script, node.js route, or servlet url
    data: {myObj: $scope.myModelObj},
    file: file,
    fileFormDataName: "myFile"
}).progress(function(evt) {
    console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers, config) {
    // file is uploaded successfully
    console.log(data);
});

in angular and then get the file as

request.getFile('myFile') 

in Grails side to see if it works.

Also see, instead of explicitly adding a fileFormDataName just rectify that you have removed the trailing , from file: file, and use as earlier, if that helps.



回答2:

The issue has been fixed. Just need to bind the post with a name, by adding fileFormDataName:"file" in the $scope.upload method.

Here is a sample,

//inject angular file upload directives and service.
angular.module('myApp', ['angularFileUpload']);

var MyCtrl = [ '$scope', '$upload', function($scope, $upload) {
  $scope.onFileSelect = function($files) {
    //$files: an array of files selected, each file has name, size, and type.
    for (var i = 0; i < $files.length; i++) {
      var file = $files[i];
      $scope.upload = $upload.upload({
        url: 'GrailsApp/upload', //upload.php script, node.js route, or servlet url
        data: {myObj: $scope.myModelObj},
        file: file,
        fileFormDataName:'file'
      }).progress(function(evt) {
        console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
      }).success(function(data, status, headers, config) {
        // file is uploaded successfully
        console.log(data);
      });
    }
  };
}];