How to clear a file input from Angular JS

All we need is an easy explanation of the problem, so here it is.

In AngularJS, I’m using the approach described here to handle input type=file.

Markup:

<div ng-controller="MyCtrl">
    <input type="file" onchange="angular.element(this).scope().setFile(this)">
    {{theFile.name}}
</div>

Controller:

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', function($scope) {
    $scope.setFile = function(element) {
        $scope.$apply(function($scope) {
            $scope.theFile = element.files[0];
        });
    };
});

As mentioned it’s a bit of a hack, but it mostly works for my purposes. What I need however is a way to clear the file input after the upload has finished – ie: from the controller.

I could completely hack it and use jQuery or something to find the input element and clear it, but was hoping for something a little more elegant.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Upon a successful upload, I clear up the input type file elements explicitly from my controller, like so:

  angular.forEach(
    angular.element("input[type='file']"),
    function(inputElem) {
      angular.element(inputElem).val(null);
    });

The input[type='file'] selector requires jQuery, but everything else is plain Angular.

Method 2

I would definitely use directive for this kind of task.

http://plnkr.co/edit/xLM9VX

app.directive('fileSelect', function() {
  var template = '<input type="file" name="files"/>';
  return function( scope, elem, attrs ) {
    var selector = $( template );
    elem.append(selector);
    selector.bind('change', function( event ) {
      scope.$apply(function() {
        scope[ attrs.fileSelect ] = event.originalEvent.target.files;
      });
    });
    scope.$watch(attrs.fileSelect, function(file) {
      selector.val(file);
    });
  };
});

note: it is using jquery for element creation.

Method 3

my solution without using $scope.

app.directive('fileChange',['UploadService',function (UploadService) {
    var linker = function (element, attrs) {
        element.bind('change', function (event) {
            var files = event.target.files;
            UploadService.upload({'name':attrs['name'],'file':files[0]});
            element.val(null);  // clear input
        });
    };
    return {
        restrict: 'A',
        link: linker
    };
}]);

Method 4

It might help you!!

HTML code sample

 <input type="file" id="fileMobile" file-model="myFile">
 <button type="button" class="btn btn-danger" id="i-agree" ng-click="uploadFile()"> Upload </button>

AngularJs code sample

$scope.uploadFile = function () {
    var file = $scope.myFile;
    mobileService.uploadBulkFile(file).then(function (resp) {
        if (resp !== undefined) {
            $('#fileMobile').val('');
        }
    });
};

Method 5

You can use ID to reset file field.

<div class="col-md-8">  
    <label for="files">Select File</label>
    <input type="file" id="file_upload" class="form-control">
</div>

After uploading clear it.

var fileElement = angular.element('#file_upload');
angular.element(fileElement).val(null);

Above example working good for me. Will work for you too.

Method 6

In my case, I broadcast events when a file upload succeeds.
So my directive watches for the broadcast, and clears the selection.

app.directive("fileInput", function( APP_EVENTS ){
    return{
        require: "ngModel",
        link: function postLink( scope, elem, attrs, ngModel ){

            elem.on("change", function( e ){
                var files=elem[0].files;
                ngModel.$setViewValue( files );
            });

            scope.$on( APP_EVENTS.FILE_UPLOAD_SUCCESS, function( event ){
                elem.val( null );
            });
        }
    }
});

It’s used like so:

<input type="file" name="myFieldName" ng-model="myModel" file-input/>

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply