Dowemo
0 0 0 0


Question:

My AngulaJS driven frontend gets the data from a local JSON file and will later switch to an API. The data is a list of Project objects with nested lists of Image objects. I'm displaying this data in a loop:

<div id="projects" ng-app="portfolio">
    <div id="projectsList" ng-controller="ProjectsListController as projectsList">
        <div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects">
            <div class="project-image">
                <img
                    ng-src="{{projectItem._embedded.images[0].src}}"
                    title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                    alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                />
            </div>
        </div>
    </div>
</div>

But sometimes the image src is invalid (error 404). It would be better to skip such projects, where the first image (images[0]) cannot be found. How to make the script skip the irrelevant objects?

EDIT

I've already got three answers, but the solutions don't work and I want to explain the problem exactly:

The src property of the images is alwys set. It's not the problem. That means, that checking if it's set or not (like ng-show="projectItem._embedded.images[0].src != ''" or ng-if="{{projectItem._embedded.images[0].src}}") will not work -- cannot work.

It doesn't work -- the src property is set. It's wrong (will cuase the 404 error), but it's set and projectItem._embedded.images[0].src != '' will return true for the "irrelevant" objects as well.

enter image description here

enter image description here


Best Answer:


This is a hacky way of making this work:

To avoid loading images when they throw 404 error or when the images are invalid,

This must be inside your controller. This function checks whether the image URL is valid/invalid.

$scope.imageExists = function(image, object, index) {
    var img = new Image();
    img.onload = function() {
      object[index] = true;
      $scope.$apply();
    }; 
    img.onerror = function() {
      return false;
    };
    img.src = image;
 };

Now in View:

I'm initiating an object called img={}; in the ng-repeat.

Then initializing the value for that index in ng-repeat to $scope.imageExists function. Inside that function, on success of that image load, am setting img[index]= true.

<div ng-repeat="image in images" ng-init="img = {}">
   <img ng-src="{{image}}" ng-init="img[$index] = imageExists(image, img, $index)" ng-show="img[$index]">
</div>

DEMO

So applying it to your code:

<div id="projects" ng-app="portfolio">
    <div id="projectsList" ng-controller="ProjectsListController as projectsList">
        <div class="projectItem" ng-repeat="projectItem in projectsList.projectsListData._embedded.projects"  ng-init="img = {}">
            <div class="project-image" ng-init="img[$index] = imageExists(projectItem._embedded.images[0].src, img, $index)" ng-show="img[$index]">
                <img
                    ng-src="{{projectItem._embedded.images[0].src}}"
                    title="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                    alt="{{projectItem.title}} - {{projectItem._embedded.images[0].title}}"
                />
            </div>
        </div>
    </div>
</div>

Place the $scope.imageExists code from above to your controller.




Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs