0

I'm using next directive to splice array if image src error.

myApp.directive("noImage", function () {
    return {
        link: function (scope, element, attrs) {
            element.bind("error", function () {
                var idx = scope.posts.indexOf(scope.post);
                scope.$apply(function () {
                    scope.posts.splice(idx, 1);
                });
            });
        }
    };
});

And trying to push spliced items back with function from controller something like.

$scope.restorePosts = (function() {
      return function() {
          $scope.spliced_posts.forEach(function(x) {
          return $scope.posts.push(x);
        });
        return $scope.spliced_posts = [];
      };
    });

The question is what i should add to directive? scope.spliced_posts.push(scope.post)?

JSFIDDLE

3
  • What action in your directive should call restorePoints(). As you are inheriting the scope from your controller, i believe that's the default when you don't define scope in your directive function declaration, you should just be able to call $scope.restorePoints(). Commented Nov 2, 2015 at 7:56
  • Not quite sure what you want to accomplish here. If you want to display the images that do not have an error, you could use a filter. Commented Nov 2, 2015 at 7:57
  • @JasperZelf The directive removed items from array if image if image src is not exist. I need to restore this spliced items back with a function from controller. Commented Nov 2, 2015 at 8:06

2 Answers 2

1

If I'm correct, you want to only show the images that have no "error.jpg" in them.

Removing them and later adding them to your array might not be the best solution here. You can use a filter with your ng-repeat to filter out the images with error.jpg in it.

ng-repeat="post in posts | filter:{ image_url:'!http://example.com/error.jpg'}"

If anywhere else you want to add a class to images that DO have the error in it, you can use ng-class:

ng-class="{'no-img': post.image_url=='http://example.com/error.jpg'}" ng-src="{{post.image_url}}"

http://jsfiddle.net/jkrielaars/xxL0qyy6/3/

That way your array of posts remains intact. If you want to be able to toggle between showing the posts with and without error.jpg, you could toggle the filter instead of changing your posts array.

in your controller

$scope.myFilter = null;
$scope.toggleFilter = function(){
    if( $scope.myFilter ){
        $scope.myFilter = null;
    }else{
        $scope.myFilter = { image_url:'!http://example.com/error.jpg' };
    }
}

and in the view:

<li ng-repeat="post in posts | filter:myFilter">

UPDATE

If you want to do dynamic checking to see if the image triggers an error, you can use a directive, much like the one you originally used, to add a class, or completely hide the element. I have also updated the JSfiddle. Something like this would add an error class to the parent. You could change this to whatever you like to style your parent. You could also choose to just hide the parent straight from the directive.

myApp.directive("hideNoImage", function () {
    return {
        link: function (scope, element, attrs) {
            element.bind("error", function () {
                element.parent().addClass("error");       
            });
        }
    };
});
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for this. The http://example.com/error.jpg is not static url, it's just an example. It can be any url where image src is not existed. So thats why i using directive with the element.bind("error", function ()
@Samual K: in that case a directive to check the images is a good approach. However, I would still not edit the original array of posts. I've updated my answer to include this option.
The another reason why i splice array is that i using limitTo (check my original fiddle) and in case of display:none or element.parent().remove() the next item not pushed to ng-repeat.
hmmm... In that case, maybe you could use your directive to add an extra attribute to the post object, and filter out objects with that extra attribute....
Thanks, for your help. I found solution. I passed limitTo value as scope, and then count how many items has error and then plus sum to limitTo number.
0

Use angular.copy() to make a copy of the original array that you receive from your api and store in your service

1 Comment

Thanks! I don't knew about that.

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.