3

I have the following:

$scope.jsonmarkers = [{
    "name": "Jeff",
        "type": "Organisation + Training Entity",
        "userID": "1"
}, {
    "name": "Fred",
        "type": "Organisation + Training Entity",
        "userID": "2"
}];

And this in my html:

<select id="typeselect"  multiple  ng-options="accnts.type for accnts in jsonmarkers" ng-model="accnt" ng-change="changeaccnt(accnt.type)"></select>

How do I go about matching the type and only echoing it once per appearance in the ng-options?

2 Answers 2

9

For removing duplicates you could use the unique filter from AngularUI (source code available here: AngularUI unique filter) and use it directly in the ng-options (or ng-repeat).

Look here for more: Unique & Stuff

Also there's a syntax error in json structure.

Working Code

Html

<div ng-app="app">
    <div ng-controller="MainController">
        <select id="typeselect"  ng-options="accnts.type for accnts in jsonmarkers | unique:'type'" ng-model="accnt" ng-change="changeaccnt(accnt.type)" multiple></select>
    </div>
</div>

script

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

app.controller("MainController", function ($scope) {
    $scope.jsonmarkers = [{
        "name": "Jeff",
            "type": "Organisation + Training Entity",
            "userID": "1"
    }, {
        "name": "Fred",
            "type": "Organisation + Training Entity",
            "userID": "2"
    }];
});


app.filter('unique', function () {

    return function (items, filterOn) {

        if (filterOn === false) {
            return items;
        }

        if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
            var hashCheck = {}, newItems = [];

            var extractValueToCompare = function (item) {
                if (angular.isObject(item) && angular.isString(filterOn)) {
                    return item[filterOn];
                } else {
                    return item;
                }
            };

            angular.forEach(items, function (item) {
                var valueToCheck, isDuplicate = false;

                for (var i = 0; i < newItems.length; i++) {
                    if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
                        isDuplicate = true;
                        break;
                    }
                }
                if (!isDuplicate) {
                    newItems.push(item);
                }

            });
            items = newItems;
        }
        return items;
    };
});
Sign up to request clarification or add additional context in comments.

2 Comments

I need Organisation + Training Entity only once not twice
Hi @vimes1984 please look at this quesion and I am looking for same answer please update my plunker as well to know the exact solution stackoverflow.com/questions/47453677/… thanks
1

I modified the answer that NidhishKrishnan gave in order to make the answer work for nested objects.

For example if you have:

$scope.jsonmarkers = [{
    "name": "Jeff",
    "type": "Organisation + Training Entity",
    "userID": "1",
    "userData": {
        "hire reason":"training"
    }
}, {
    "name": "Fred",
    "type": "Organisation + Training Entity",
    "userID": "2"
    "userData": {
        "hire reason":"training"
    }
}];

This is the modified version:

angular.module('ArtifactFeederApp.filters', [])

    .filter('unique', function () {
    return function (items, filterOn) {

        if (filterOn === false) {
            return items;
        }

        if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
            var hashCheck = {}, newItems = [];

            var extractValueToCompare = function (item) {
                if (angular.isObject(item) && angular.isString(filterOn)) {

                    var resolveSearch = function(object, keyString){
                        if(typeof object == 'undefined'){
                            return object;
                        }
                        var values = keyString.split(".");
                        var firstValue = values[0];
                        keyString = keyString.replace(firstValue + ".", "");
                        if(values.length > 1){
                            return resolveSearch(object[firstValue], keyString);
                        } else {
                            return object[firstValue];
                        }
                    }

                    return resolveSearch(item, filterOn);
                } else {
                    return item;
                }
            };

            angular.forEach(items, function (item) {
                var valueToCheck, isDuplicate = false;

                for (var i = 0; i < newItems.length; i++) {
                    if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
                        isDuplicate = true;
                        break;
                    }
                }
                if (!isDuplicate) {
                    if(typeof item != 'undefined'){
                        newItems.push(item);
                    }
                }

            });
            items = newItems;
        }
        return items;
    };
});

You can now do:

<div ng-controller="MainController">
    <select id="typeselect"  ng-options="accnts.type for accnts in jsonmarkers | unique:'userData.hire reason'" ng-model="accnt" ng-change="changeaccnt(accnt.type)" multiple></select>
</div>

And you will see a list that only shows training as an option.

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.