5

I'm trying to display a list of files which the user selects using the input[type=file].

HTML

<div ng-app="myApp">
    <div ng-controller="UploadFilesCtrl">
        <input type="file" onchange="angular.element(this).scope().uploadFiles(this)" multiple />
        <ul>
            <li ng-repeat="name in filenames">
                {{name}}
            </li>
        </ul>
        <button ng-click="test()">PRINT</button>
    </div>
</div>

JS

app = angular.module('myApp');

app.controller('UploadFilesCtrl', ['$scope', function($scope){

    $scope.uploadFiles = function(element){

        var files = element.files;
        var filenames=[];

        for (i=0; i<files.length; i++){
            filenames.push(files[i].name);
        }


        $scope.files = files;
        $scope.filenames = filenames;   
        console.log(files, filenames);
    };


    $scope.test = function(){
        console.log($scope.files, $scope.filenames);
    }
}]);

From some reason the list never gets updated.

The filenames and files variables in the $scope never get updated outside of the uploadFiles function (When I click the PRINT button after selecting file I get undefined).

Any ideas?

Thanks!

5
  • angular.element(this).scope().uploadFiles(this) I would imagine this isn't causing an angular digest. This seems like a job for a directive instead, but in the mean time you can try $scope.$apply(function() { $scope.files = files; }); to see if it is actually a digest issue Commented Apr 21, 2015 at 7:17
  • I just found the answer you got this snippet from. You should read the comments before assuming the accepted answer is correct :) Commented Apr 21, 2015 at 7:24
  • did you got any error? Commented Apr 21, 2015 at 7:36
  • $scope.apply doesn't do the job from some reason. I ended up trying to create a directive. Thanks! Commented Apr 21, 2015 at 16:13
  • This Work Fine in Crome and IE but not work in Firefox in firefox it give error like TypeError: angular.element(...).scope(...).uploadFiles is not a function Commented Apr 18, 2018 at 12:24

2 Answers 2

2

You don't need $scope.$apply()

...............................................................................................................................................................

Your codes are looking very nice. and it's should be working if you did my below thing.

But you have missed only one thing. but that's main thing.

I think you may be got this below error

Uncaught Error: [$injector:modulerr] Failed to instantiate module myApp due to: Error: [$injector:nomod] Module 'myApp' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.

please verify in your browser console window, if you got this error,then Please try this

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

instead of

app = angular.module('myApp');

You have missed empty sub models in main model('myApp',[]);

All other codes looks well.

Update :

Please see this fiddler Demo , Now your selected files names are displayed when you click print button.

Sign up to request clarification or add additional context in comments.

4 Comments

@ameshrajendran I didn't downvoted this, but your answer is not correct? You understood it wrong, I think OP has done it..
@RameshRajendran. -1 , your very first line is not the answer to OP's question.
The first line not for OP, that's for @Sourabh- answer
@RameshRajendran. You can do that in comments. Anyways removed the downvote. :)
2

Use $scope.$apply() to update your $scope objects

...
$scope.files = files;
$scope.filenames = filenames;   
$scope.$apply();
console.log(files, filenames);
...

Rest is working fine.

EDIT:

RGraham is correct. This is not a full proof solution. You should use directive instead. But just for a work around you can do a check if digest is in progress like this :

if ($scope.$root.$$phase != '$apply' && $scope.$root.$$phase != '$digest') {
    $scope.$apply();
}

Updated fiddle : http://jsfiddle.net/Sourabh_/HB7LU/13086/

1 Comment

That's not a very good solution. It's fine for debugging, but OP should switch to using a directive where they don't need $scope.$apply. Your code will cause an error if a digest is already in progress.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.