2

The task is to show image in template, but only if image dimensions ratio > 2

<img class="main-img" ng-if="showImage($index)" ng-src="{{item.img}}">

Function:

$scope.showImage = function(index) {
    var img = new Image();
    img.src = $scope.items[index].img;
    img.addEventListener("load", function() {
        var ratio = this.naturalWidth / this.naturalHeight;
        if (ratio > 2) {
            return true;
        } else {
            return false;
        }
    })
}

ng-if doesn't wait for image loading. How to fix? Thanks.

4 Answers 4

1

By running $scope.$apply() at the end of your function, you can force angular to load the images.

$scope.showImage = function(index) {
  var img = new Image();
  img.src = $scope.items[index].img;
  img.addEventListener("load", function() {
      var ratio = this.naturalWidth / this.naturalHeight;
      if (ratio > 2) {
          return true;
      } else {
          return false;
      }
   })
  $scope.apply()
}
Sign up to request clarification or add additional context in comments.

1 Comment

Yes sir, that is most direct and correct answer, just force model change. Why is this not the accepted answer? Because most programmers are "Beethoven's" at heart, and love to write symphonies for answers :).
1
<img class="main-img" ng-init="showImage($index)" ng-if="ImageLoad" ng-src="{{item.img}}">

$scope.ImageLoad=false;
$scope.showImage = function(index) {
    var img = new Image();
    img.src = $scope.items[index].img;
    img.addEventListener("load", function() {
        var ratio = this.naturalWidth / this.naturalHeight;
        if (ratio > 2) {
            $scope.ImageLoad=true;
            return true;
        } else {
            return false;
        }
    })
}

Change like this

3 Comments

This code is wrapped by ng-repeat, so none of images will be shown if this function will return False.
ok, you can try with index $scope.ImageLoad=[]; and inside the function set index $scope.ImageLoad[index]=true and in img tag set ng-if="ImageLoad[$index] if you have any issue let me know.
you may need $timeout somewhere in there.
1

In the above mentioned code I believe instead of ng-if it should be 'ng-init'. If you are wrapping the code with ng-repeat none of the images will be shown as per the function you have provided. Also you can set a timeout.

Comments

0

looks like these events are happening outside of angular's digest cycle. $apply should work but you could also forgo the event listener and bind to a function that returns false until the needed attributes are there, but those can be expensive. this approach would work too, putting load event/listening on image in a directive, then can either call a $scope method or $broadcast to manage the flag for ng-if. see this example: Image loaded event in for ng-src in AngularJS

Comments

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.