Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I'm trying to get angular to read the contents of a file that the user selects through an <input type="file" control. Even though angular does not have directives for file upload controls, it should be easy to fix that with a call to $apply:

function MyController($scope) {
  $('#myFile').on('change', function() {
    var that = this;
    $scope.$apply(function() { $scope.files = that.files });
  });
}

Unfortunately, the event is never fired. It's like the selector is unable to refer to the correct DOM element: even though the selector finds the element, the list of files is always empty. This also happens if i poke around with the js console. The DOM inspector instead has the file list among its properties.

It's driving me crazy, but the only way I've got it to work so far is to use an inline event handler that assigns to a global variable. Why is the jquery selector returning another item? Is there some template compilation mumbo-jumbo that angular does which confuses selectors?

share|improve this question

2 Answers 2

up vote 7 down vote accepted

Here is what I do:

http://plnkr.co/edit/JPxSCyrxosVXfZnzEIuS?p=preview

app.directive('filelistBind', function() {
  return function( scope, elm, attrs ) {
    elm.bind('change', function( evt ) {
      scope.$apply(function() {
        scope[ attrs.name ] = evt.target.files;
        console.log( scope[ attrs.name ] );
      });
    });
  };
});

template:

<input type="file" filelist-bind name="files"/>
<p>selected files : <pre>{{ files | json }}</pre></p>

This kind of task, you definitely want to make use of directive. But I think that your main concern is how to access the selected file objects and my example should clarify that.

share|improve this answer
    
nice. I ended up defining a global function in the controller, and calling it from the inline event handler. Since $scope is in the outer closure, at least I can $apply the changes. The directive is definitely a more "angular" way to do it. But the question stands: why does the selector returns an input element that looks exactly like the one the user is interacting with, but it actually isn't? –  BruceBerry May 16 '13 at 15:22

If you are looking for file upload with angular you can use this plugin

https://github.com/danialfarid/angular-file-upload

It is basically a directive like tosh's answer that takes care of non-HTML5 browsers with FileAPI flash polyfill and has $http.uploadFile function to upload the actual file via AJAX.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.