0

So here's the deal; I have this $watch which is set on a file input, and checks if a new file is selected. After a new file (usually an image) is selected, thus triggering the watch, I want these 3 things to happen:

1-a flag ( imgAvailable) be set to 1;

2-a preview of image be shown; which needs image to be saved into $rootScope.img2;

3-selected image be pushed to an array ( $rootScope.imgs or myTestVariable);

The first two happen, however, the third one does not.

This is my watch; Note that this watch runs in main controller of this page, rootScope.imgs = [] was defined in the controller of previous page, and var myTestVariable = rootScope.imgs

$scope.$watch('file', function(newfile, oldfile, scope) {
                if(angular.equals(newfile, oldfile) ){
                    return;
                }
                scope.$root.img2 = image;
                myTestVariable.push(image);
                scope.imgAvailable = true;

            },
            function (newfile,oldfile,scope){
                scope.$apply(function() {
                    scope.$root.img2 = newfile;
                    scope.$root.imgs.push(newfile);
                });
            });

This is the input which the $watch is set on:

<input type="file" fileinput="file" filepreview="filepreview" id="myIngSelector"/>

Edit: I though I would be irrelevant, but fileinput is this directive:

.directive("fileinput", [function() {
        return {
            scope: {
                fileinput: "=",
                filepreview: "="
            },
            link: function(scope, element, attributes) {
                element.bind("change", function(changeEvent) {
                    scope.fileinput = changeEvent.target.files[0];
                    var reader = new FileReader();
                    reader.onload = function(loadEvent) {
                        scope.$apply(function() {
                            scope.filepreview = loadEvent.target.result;
                            scope.$root.img2=scope.fileinput;
                        });
                    }
                    reader.readAsDataURL(scope.fileinput);
                });
            }
        }
    }])

After I select image and check my inspect page, both myTestVariable and rootScope.imgs are equal to [], so basically nothing has happened and no img was pushed in any of these two arrays.

What I have tried:

  • defining rootScope.imgs in this controller; no change.
  • calling an external function instead of $apply; no change; - I actually hoped to be able to trace it line by line, however I gained no success. :D
  • change rootScope.imgs to scope.imgs; results in undefined;
  • push image to rootScope.imgs outside watch manually; It works. So generally that images can be pushed into rootScope.imgs. It just does not happen in the watch.

Please pay attention that the $watch is not on array itself; It is on a file input.

What should I do to be able to push objects into array inside a $watch on that object?

Any amount of help will be highly appreciated.

Sarah_A
  • 150
  • 4
  • 18

1 Answers1

0

I am wondering why you not tried ng-change:

<input type="file" fileinput="file" ng-model="myFile" ng-change="func(myFile) filepreview="filepreview" id="myIngSelector"/> 

In your code :

$scope.$watch('file', function(newfile, oldfile, scope) { }

What is file here?
Is this a $scope variable?
If not than how $watch will work?

If you want to use $watch(you should not) instead ng-change than add a ng-model directive in file input and than assign that value to $watch.

  <input type="file" fileinput="file" ng-model="myFile"  filepreview="filepreview" id="myIngSelector"/> 
 $scope.$watch('myFile', function(newfile, oldfile, scope) { }
Ved
  • 11,837
  • 5
  • 42
  • 60
  • I am brutally sorry. I didn't think the directive would be relevant so I did not add it there. The change will be handled in the directive which I added here :D – Sarah_A Dec 14 '17 at 11:49
  • Anyway here is answer for your question.: https://stackoverflow.com/questions/17063000/ng-model-for-input-type-file – Ved Dec 14 '17 at 11:53
  • so you mean I must change my whole directive in order to be able to push my image to my array? I had no problem with reading the file, though. – Sarah_A Dec 14 '17 at 11:56
  • No. I do not mean that. I shared the link to understand the logic behind it. Implementation is your own. – Ved Dec 14 '17 at 11:57
  • I guess I'm missing something here. I can read my image, I just can not push my image to my array in the watch associated to that input image tag. The accepted answer of that question is really similar to my directive. So...um...I still feel I'm missing something here. By the way I tried your suggested code at the end of your post and it still does not push anything into my array. – Sarah_A Dec 14 '17 at 12:04
  • How you are checking the value inside array. I don't see any console.log there. – Ved Dec 14 '17 at 12:08
  • I add them to watch when I use chrome:inspect – Sarah_A Dec 14 '17 at 12:10