c f
c f

Reputation: 196

angularJS - How to filter by one item in object only

In this JSFiddle (https://jsfiddle.net/eug0taf9/9/), I select a rating and expect an image to be displayed.

What is happening?

When I select rating 'High', 2 images show up instead of 1 because the filter is catching category 'High' and also description 'High' of an image in category 'Low'.

What do I expect to happen?

On selecting rating "High", I only want the category to be filtered. I don't need it to be filtered by description too.

Any suggestions on how to solve this?

HTML code:

<div ng-app="myApp" ng-controller="myCtrl">
    <span>Select a rating</span>
    <select ng-model="catselect"
            ng-options="category for category in imageCategories"
            ng-change="valueSelected(catselect)">
        <option value>All</option>
    </select>
    <!--<p>Select <input ng-model="categories"/></p>-->

    <ul class="photosmenu">
        <li ng-repeat="image in images | filter : catselect" ng-click="setCurrentImage(image)">
            <img ng-src="{{image.image}}" alt="{{image.stars}}" width="300px"/>
        </li>
    </ul><!-- End of List -->
</div>

Angular Code:

var mod = angular.module("myApp", []);

mod.controller("myCtrl", function($scope){
    $scope.images = [
        {category: 'High', image: 'img/1.png', description: 'Random Photo', stars: '4/5'},
        {category: 'Medium', image: 'img/6.png', description: 'ApplePhoto', stars: '3/5'},
        {category: 'Low', image: 'img/13.png', description: 'High Top Photo', stars: '2/5'},
        {category: 'None', image: 'img/16.png', description: 'Kilt Photo', stars: '0/5'}];

    $scope.currentImage = $scope.images[0];
    $scope.imageCategories = ["High", "Medium", "Low", "None"];

    $scope.valueSelected = function (value) {

        if (value === null) {
            $scope.catselect = undefined;
        }
    };    

});

Upvotes: 0

Views: 2728

Answers (1)

PSL
PSL

Reputation: 123749

That is because you have a global match filter which will match on all properties, if you want to filter on specific property set your filter object accordingly. i.e

<li ng-repeat="image in images | filter :{category: catselect}"

Demo

or you could also set your ng-model to an object,

<select ng-model="catselect.category"

and do:

<li ng-repeat="image in images | filter :catselect"

Demo

Check out documentation:

string: The string is used for matching against the contents of the array. All strings or objects with string properties in array that match this string will be returned. This also applies to nested object properties. The predicate can be negated by prefixing the string with !.

Object: A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1". A special property name $ can be used (as in {$:"text"}) to accept a match against any property of the object or its nested object properties. That's equivalent to the simple substring match with a string as described above. The predicate can be negated by prefixing the string with !. For example {name: "!M"} predicate will return an array of items which have property name not containing "M".

Upvotes: 1

Related Questions