Arthur Eudeline
Arthur Eudeline

Reputation: 655

Check if object is in another object array in ng-repeat

I'm listing a list of regions from a GET request under the form of a list of checkbox (I'm using ng-repeat for this) and all je checkbox which are checked are saved in an object array in JSON into localStorage. But I can't find a way to pre-check the checkbox that the user have checked before. I tried to use indexOf or includes but it didn't work

There is the code if you can help me. The App is build on Ionic Cordova v1 :

View loop

<li ng-repeat="region in regionFilteredList = (regionList | filter:{name : search}) track by region.id">
    <ion-checkbox class="item-checkbox-right" ng-model="selected" ng-checked="selectAll" ng-click="toggleSelection(region)">
        {{ region.name }}
    </ion-checkbox>
</li>

Controller

APP.controller('SettingsRegionController', function($rootScope, $scope, $http){

    // Regions already selected
    $scope.selectedRegions = JSON.parse(localStorage.getItem('userSubscribedRegions'));

    // GET request
    $http.get( 'http://unsasj-v2.originis.fr/wp-json/wp/v2/region?per_page=100').then(
        // Sucess
        function(response){
            $scope.regionList = response.data;
        },

        // En cas d'erreur
        function(error){
            console.log(error);
        }
    );

});

Attemps

$scope.selectedRegions.indexOf($scope.regionList[0]); // return -1

$scope.selectedRegions.includes($scope.regionList[0]); // return false

$scope.checkTest = function(valueToFind, arrayToSearch){
    for(var i = 0; i < arrayToSearch.length; i++){
        if(arrayToSearch[i] == valueToFind.id){
            return true;
        }
    }
};

JSON Data

$scope.selectedRegions = [{"id":121,"name":"Alsace-Lorraine","slug":"alsace-lorraine","$$hashKey":"object:48"},{"id":122,"name":"Aquitaine","slug":"aquitaine","$$hashKey":"object:49"},{"id":123,"name":"Corse","slug":"corse","$$hashKey":"object:52"},{"id":125,"name":"DOM-TOM","slug":"dom-tom","$$hashKey":"object:53"},{"id":122,"name":"Aquitaine","slug":"aquitaine","$$hashKey":"object:57"}];

$scope.regionList = [{"id":121,"name":"Alsace-Lorraine","slug":"alsace-lorraine"},{"id":122,"name":"Aquitaine","slug":"aquitaine"},{"id":120,"name":"Centre-Limousin","slug":"centre-limousin"},{"id":124,"name":"Champagne - Bourgogne - Franche-Comté","slug":"champagne-bourgogne-franche-comte"},{"id":123,"name":"Corse","slug":"corse"},{"id":125,"name":"DOM-TOM","slug":"dom-tom"},{"id":126,"name":"Ile-de-France","slug":"ile-de-france"},{"id":127,"name":"Languedoc-Rousillon - Midi-Pyrénées","slug":"languedoc-rousillon-midi-pyrenees"},{"id":128,"name":"Nord","slug":"nord"},{"id":129,"name":"Ouest","slug":"ouest"},{"id":130,"name":"PACA","slug":"paca"},{"id":131,"name":"Poitou-Charentes - Pays de la Loire","slug":"poitou-charentes-pays-de-la-loire"},{"id":132,"name":"Rhône-Alpes - Auvergne","slug":"rhone-alpes-auvergne"}]

Upvotes: 0

Views: 48

Answers (2)

Arthur Eudeline
Arthur Eudeline

Reputation: 655

The answer given by Protozoid works for me after a quick edit on toggleSelectAll function. For those that it can help there is the solution :

In the view : I've added an argument on ng-change directive in order to get the current state of the checkbox (if it's checked or not) at the moment where toggleSelectAll is fired :

<ion-checkbox class="item-checkbox-right item-divider" ng-model="selectAll" ng-change="toggleSelectAll(selectAll)">
    Select all
</ion-checkbox>

And in controller

$scope.toggleSelectAll = function (isChecked) {
    if($scope.regionList){
        $scope.regionList.forEach(function (region) {
            region.selected = isChecked;
        });
    }
}

Hope it can help

Upvotes: 1

Protozoid
Protozoid

Reputation: 1207

I believe the issue is that ng-model="selected" doesn't actually point to anything individual to each region. The way AngularJS would interpret that is there's a selected property on $scope ... which isn't the case.

Instead, you should have a selected property for each region, so that you can check/uncheck individual regions, as such:

APP.controller('SettingsRegionController', function($rootScope, $scope, $http){

    // Regions already selected
    $scope.selectedRegions = JSON.parse(localStorage.getItem('userSubscribedRegions'));

    // GET request
    $http.get( 'http://unsasj-v2.originis.fr/wp-json/wp/v2/region?per_page=100').then(
        // Sucess
        function(response){
            $scope.regionList = response.data;

            $scope.regionList.forEach(function (region) {
                region.selected = false;
                $scope.selectedRegions.forEach(function (selectedRegion) {
                    if (selectedRegion.id == region.id) {
                        region.selected = true;
                    }

                });
            });
        },

        // En cas d'erreur
        function(error){
            console.log(error);
        }
    );

});

And in HTML ng-model="region.selected", as such:

<li ng-repeat="region in regionFilteredList = (regionList | filter:{name : search}) track by region.id">
    <ion-checkbox class="item-checkbox-right" ng-model="region.selected">
        {{ region.name }}
    </ion-checkbox>
</li>

Notes:

Removed ng-click="toggleSelection(region)" because the toggling between true/false is handled by ng-model. If you want extra functionality on that event, use ng-change. Docs here

Removed ng-checked="selectAll". If you want selectAll functionality, you should implement a master checkbox and set selected to true for all regions when this checkbox changes

e.g. a very simplistic implementation:

In HTML:

<ion-checkbox class="item-checkbox-right" ng-model="selectAll" ng-change="toggleSelectAll()">
    Select all
</ion-checkbox>

And in your controller:

// Initialise selectAll as false
$scope.selectAll = false;

$scope.toggleSelectAll = function () {
    $scope.regionList.forEach(function (region) {
        region.selected = $scope.selectAll;
    }
}

Upvotes: 0

Related Questions