0

I have this directive, which basically attaches a file to a model through file-model="..." (the entire purpose of this directive is because ng-model doesn't work in <input type="file"> in angularjs)

angular.module('myApp').directive('fileModel', ['$parse', function ($parse) {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {

            console.log(scope); // DEBUG

            var model = $parse(attrs.fileModel);

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

                if (attrs.ngChange) {
                    scope.$apply(attrs.ngChange); 
                }
            });
        }
    };
}]);

And I also have a bootstrap-ui modal, modal.html:

<div class="modal-body">   
    <div class="form-group">
        <input type="file" file-model="excelFile" ng-model="dummy" ng-change="uploadFile()" />
    </div>
</div>

With its corresponding bootstrap-ui controller:

angular.module('myApp').controller('modalController', ['$scope', '$modalInstance', '$scope', function ($scope, $modalInstance, $scope) {

    $scope.uploadFile = function() {
        console.log($scope); // DEBUG

        var formData = new FormData();
        formData.append('file', $scope.excelFile); // empty!

        ...
    };
}]);

I invoke the modal from another controller like this:

$scope.openModal = function () {

    var modalScope = $scope.$new();

    modalScope.somePassedData = "I pass data this way";

    var modalInstance = $modal.open({
        templateUrl: 'views/modal.html',
        controller: 'modalController',
        scope: modalScope,
    });

    ...
};

So... if you notice the three comments:

  1. First comment // DEBUG
  2. Second comment // DEBUG
  3. Comment // empty!

It seems that the scope used by the directive is not the same as the scope where the <input type="file"> is living, and because of this I'm getting an empty file.

What am I doing wrong with scopes?

Also I should mention that this worked fine without using bootstrap ui-modal... so it must have something to do with the scope of the modal

sports
  • 7,851
  • 14
  • 72
  • 129
  • The answer is here: `var modalScope = $scope.$new();`. `$scope.$new()` creates a new child scope that inherits from `$scope`. So anything in `$scope` should be in `modalScope` too. But you are saying that you "invoke the modal from another controller". Controllers have isolated scopes, so most likely `$scope.excelFile` is in another scope than `modalScope`, right? – Sergiu Paraschiv Oct 07 '14 at 14:32
  • You've seen [this related SO post](http://stackoverflow.com/questions/18716113/scope-issue-in-angularjs-using-angularui-bootstrap-modal?rq=1) right, and you tried to initialize `$scope.input={}` and it didn't work? – Michael Oct 07 '14 at 14:32
  • Sorry I'm not following you... but I did tried to initialize $scope.excelFile in the scope of the modal – sports Oct 07 '14 at 14:40
  • I read the link and it is not the case in here, because the passed scope is already initialized. The second "// DEBUG" is throwing a different scope from the first "// DEBUG". So my problem is not a null or undefined scope but a different one. – sports Oct 07 '14 at 14:52

1 Answers1

0

Two things to test:

  1. Verify that your uploadFile function is called after your directive's event handler (since they are listening to the same event). If it isn't, you should increase the priority of your fileModel directive to be greater than that of ngChange (which is 0).
  2. Try using the resolve property to pass in data to your modal instead of creating a new scope. According to the documentation, $modal creates a child scope of the one you pass in, so you may be running into the prototypal inheritance issue with your primitive value.
user1620220
  • 1,295
  • 8
  • 15
  • Regarding (1): all the directive code is being called before the uploadFile() method (checked). Regarding (2): Hmm i will try, even though for all my modals in the past I have been passing a new scope from the parent – sports Oct 07 '14 at 18:35