1

I am attempting to pass a file into a function, where the file is originated from an input type of file. My code looks something like this.

<input type="file" id="scvFileUploadId"/>

<button id="uploadFilesubmit" ng-click"ctrl.uploadFile()">Upload</button>

In short, I would like to take the file that has been added to the input and pass it into the parameter of the function of the ng-click attribute that is fired when the button is clicked. I think this may be simple, but I cannot wrap my head around it at the moment.

I'm trying to do something like this.

<input type="file" id="scvFileUploadId"/>

<button id="uploadFilesubmit" ng-click"ctrl.uploadFile(#scvFileUploadId.file)">Upload</button>
Alexander Edwards
  • 772
  • 2
  • 7
  • 18

3 Answers3

1

My solution was to use Angular's element selector to point to the input element holding the file, and then pass the result of that as the parameter into the function, like so:

<input type="file" id="scvFileUploadId" />

<button id="uploadFilesubmit" onclick="angular.element(this).controller().uploadFile(angular.element(document.querySelector('#csvFileUploadID'))[0].files[0])">Upload</button>

I'm not sure if this solution is the most 'Angular' way of doing it, but there were existing workarounds for some lack of support with Angular input file uploading being done on this part of the application that forced me to interact with DOM, so this does suffice in my scenario.

Alexander Edwards
  • 772
  • 2
  • 7
  • 18
0

I highly recommend using existing directives created by the community;

But if you are restricted and want to avoid 3rd parties you can see this implementation:

ng-model for <input type="file"/>

<input type="file" fileread="vm.uploadme" />
<button id="uploadFilesubmit" ng-click"ctrl.uploadFile(vm.uploadme)">Upload</button>
Klajd Diko
  • 36
  • 2
0

You can use a simple directive with NgModelController to add ngModel support for the input type='file' like:

angular.module('myApp', [])
.controller('TestUploadController', ['$scope', function ($scope) {
    var ctrl = this;
  
    ctrl.imageFile = null;
    
    ctrl.clearFile = clearFile;
    ctrl.uploadFile = uploadFile;
    
    function clearFile() {
      ctrl.imageFile = null;
    }
    
    function uploadFile(file) {
      if (file) {
        console.log('Upload: ', file);
      }
    }
}])
.directive('fileUpload', [function () {
  return {
    require: "ngModel",
    restrict: 'A',
    link: function ($scope, el, attrs, ngModel) {
      function onChange (event) {
        //update bindings with $applyAsync
        $scope.$applyAsync(function(){
          ngModel.$setViewValue(event.target.files[0]);
        });
      }
      //change event handler
      el.on('change', onChange);
      
      //set up a $watch for the ngModel.$viewValue
      $scope.$watch(function () {
        return ngModel.$viewValue;
      }, function (value) {
        //clear input value if model was cleared
        if (!value) {
          el.val("");
        }
      });
      //remove change event handler on $destroy
      $scope.$on('$destroy', function(){
        el.off('change', onChange);
      });
    }
  };
}]);
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.angularjs.org/1.6.2/angular.js"></script>

<div ng-app="myApp">
  <div ng-controller="TestUploadController as $ctrl">
    <input type="file" file-upload ng-model="$ctrl.imageFile" />
    <input type="button" ng-click="$ctrl.uploadFile($ctrl.imageFile)" value="Upload" />
    <input type="button" ng-click="$ctrl.clearFile()" value="Reset" />
    <div ng-if="$ctrl.imageFile">
      {{$ctrl.imageFile.name}}<br />
      {{$ctrl.imageFile.size}} byte(s)<br/>
      {{$ctrl.imageFile.type}}
    </div>
  </div>
</div>
Stanislav Kvitash
  • 4,614
  • 18
  • 29