0

I've got a directive which defines a input field of type="file", which I can print and is not empty, namely:

<form class="form-horizontal" role="form">
    <input type="file" file-model="myFile"/>
    {{myFile}} <-- this prints fine
    <button type="submit" class="btn btn-success" ng-click="saveData()">Post</button>
</form>

which I can see if called in the view

app.js

.directive('fileModel', ['$parse', function ($parse) {
return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        var model = $parse(attrs.fileModel);
        var modelSetter = model.assign;

        element.bind('change', function(){
            scope.$apply(function(){
                modelSetter(scope, element[0].files[0]);
            });
        });
      }
    };
}]);

What I am trying to do now is access the field inside my controller:

.controller('Ctrl', function($scope, fileUpload) {
    ...

    $scope.myFile; <-- initialise it 

    $scope.saveData = function() {

        var file = $scope.myFile;
        console.log(file); <-- prints out as undefined
    }



.service('fileUpload', ['$http', function ($http) {
    this.uploadFileToUrl = function(file, uploadUrl){
        var fd = new FormData();
        fd.append('file', file);
        $http.post(uploadUrl, fd, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        })
        .success(function(){

        })
        .error(function(){

        });
    }
}]);

But file is undefined.

Any ideas why that would happen and how to access the value of the field?

13
  • Have you got the code for your directive as well? Commented Aug 4, 2014 at 13:34
  • Sure. I'll edit my question Commented Aug 4, 2014 at 13:36
  • Is $scope.myFile initialized in your controller? Otherwise it will only available in the view. Commented Aug 4, 2014 at 13:56
  • Seems to work fine for me. Have you checked you have no errors in the console? Commented Aug 4, 2014 at 13:59
  • @naeramarth7: I have initialised it as $scope.myFile = {} and when trying to call the saveData() function, it prints still as Object {} Commented Aug 4, 2014 at 14:00

1 Answer 1

1

If you want to bring in attribute values to your directive, I recommend doing it like so.

.directive('myDirective', ['$parse', function ($parse) {
return {
    restrict: 'A',
    scope: {
    fileModel: '=fileModel'
    }
    link: function(scope, element, attrs) {
        var model = scope.fileModel;
        var modelSetter = model.assign;

        element.bind('change', function(){
            scope.$apply(function(){
                modelSetter(scope, element[0].files[0]);
            });
        });
      }
    };
}]);

Note I changed your directive name since you already had an attribute with that name.

<input type="file" my-directive file-model="myFile"/>

I'm not sure what you are trying to do after you have the attribute value, but if you console.log(scope.fileModel) you can see what built in options are available. This is an example of isolated scope within directives.

Update with controller access

To access within your controller, you could emit the value from your directive:

scope.$emit('myFile', scope.fileModel); 

and then listen for the event in your controller:

$scope.$on('myFile', function (event, myFile) {
    $scope.myFile = myFile;
};

Update with working fiddle

http://jsfiddle.net/jonesmac82/376SS/26/

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

5 Comments

What I am trying to do is access the value of "myFile" in the controller.
Thanks, let me have a look :)
Still throwing undefined :(
Take a look at my fiddle and see if it helps you. I think some of the complexity is that you need to get a file upload directive to work with files within angular. Let me know if you need recommendations.
I just updated it again to show how you can structure your directive to handle object values.

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.