Sohail Faruqui
Sohail Faruqui

Reputation: 452

Angular Js Filtering nested array in controller

I want to filter nested array using angularjs filter in controller. following is my sample data

dummy=[
    {
        category:'TV',
        data:[
            {
                title: 'Game of Thrones',
                path: 'some data1',
            },
            {
                title: 'Game of Thrones-SD',
                path: 'some data2'
            },
            {
                title: 'Game of Thrones-HD',
                path: 'some data3'
            },
            {
                title: 'Game of Thrones-Trailer 1',
                path: "some data4"
            },
            {
                title: 'Game of Thrones-Trailer 2',
                path: "some data5"
            },
            {
                title: 'Game of Thrones-Trailer 3',
                path: "Ssome data6"
            },
            {
                title: 'The Vampire Diaries ',
                path: 'some data7'
            },
            {
                title: 'The Vampire Diaries -SD',
                path: 'some data8'
            },
            {
                title: 'The Vampire Diaries -HD',
                path: 'some data9'
            },
            {
                title: 'The Vampire Diaries -Trailer 1',
                path: 'some data10'
            }
        ]
    },
    {
        category:'LIVE',
        data:[
            {
                title: 'Game of Thrones - Live Show',
                path: 'some data11'
            },
            {
                title: 'The Vampire Diaries  - Live Show',
                path: 'some data11'
            }
        ]
    }
];

for example i want to filter the data on title, so if i search "game of thrones" i want to get following data

    {
        category:'TV',
        data:[
            {
                title: 'Game of Thrones',
                path: 'some data1',
            },
            {
                title: 'Game of Thrones-SD',
                path: 'some data2'
            },
            {
                title: 'Game of Thrones-HD',
                path: 'some data3'
            },
            {
                title: 'Game of Thrones-Trailer 1',
                path: "some data4"
            },
            {
                title: 'Game of Thrones-Trailer 2',
                path: "some data5"
            },
            {
                title: 'Game of Thrones-Trailer 3',
                path: "Ssome data6"
            },
        ]
    },
    {
        category:'LIVE',
        data:[
            {
                title: 'Game of Thrones - Live Show',
                path: 'some data11'
            }
        ]
    }

I think similar question has been asked here Angularjs filter nested object

and i tried to use the following code in my controller but it did not worked

var filterdData = $filter('filter')(content, {data: [{title: $scope.filterKey}]});

Upvotes: 1

Views: 8425

Answers (2)

VuTam4494
VuTam4494

Reputation: 51

this worked for me

var filterdData = $filter('filter')(content, {data: {title: $scope.filterKey}});

Upvotes: 5

Fast answer:

Your screen must be something like this:

<td filter="{'Object.InnerObject': 'text'}">{{row.Object.InnerObject}}</td>

On your controller:

Add this function to convert the filters of ngTable to a JSON object that the AngularJS Filter understand.

var treatJSON = function(malformedJson){

    var treatedFilters = {};

    var subObjects = [];

    var auxiliarObject;

    var objectName;
    var objectValue;

    var keys = Object.keys(malformedJson);

    for(var index = 0; index < keys.length; index++){
        auxiliarObject = null;

        subObjects = keys[index].split('.');

        // Go adding the layers from bottom to up
        for(var innerIndex = subObjects.length - 1; innerIndex >= 0 ; innerIndex--){

            // Recovery the name and the value of actual object
            objectName = subObjects[innerIndex];
            objectValue = auxiliarObject || malformedJson[keys[index]];

            // Add the objet to the treated filters or add it to the chain for the next object to use it
            if(innerIndex == 0){
                treatedFilters[objectName] = objectValue;
            } else {
                auxiliarObject = {};
                auxiliarObject[objectName] = objectValue;
            }
        }
    }

    return treatedFilters;
};

And change the getData function to use the function above:

getData: function($defer, params) {
    var filteredRecords = 
        params.filter() 
            ? $filter('filter')($scope.records, treatJSON(params.filter()))
            : $scope.records;

    $defer.resolve(filteredRecords.slice((params.page() - 1) * params.count(), params.page() * params.count()));
    params.total(filteredRecords.length);
}

More Detailed Answer:

I had the same problem and resolved it creating a function to decompose the object passed by the view.

The problem was the object devolved by the ngTable.

When the ngTable finds a complex object on the filter attribute, it does not parse the object, returning a flat string. Ex:

This complex filter

<td filter="{'Object.InnerObject': 'text'}" class="text-right">

will be returned as

{'Object.InnerObject': ""}

However the AngularJS filter needs a well formed complex object to filter the field. Then the function just transforme the last example to this:

{
    'Object':
    {
        'InnerObject': ""
    }
}

Hope it helps.

Upvotes: 1

Related Questions