1

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}]});
5
  • Is there any reason why you need to use $filter? Can't you just use a custom filter function? Commented Feb 8, 2015 at 10:23
  • @tasseKATT : yes angular version one Commented Feb 8, 2015 at 18:13
  • 1
    One as in 1.0.0? That is really old. Commented Feb 8, 2015 at 19:03
  • @tasseKATT: sorry man typo mistake. its v1.3.12 Commented Feb 8, 2015 at 20:14
  • Did the code version work for you? Commented Mar 11, 2015 at 20:21

2 Answers 2

5

this worked for me

var filterdData = $filter('filter')(content, {data: {title: $scope.filterKey}});
Sign up to request clarification or add additional context in comments.

1 Comment

Please edit with more information. Code-only and "try this" answers are discouraged, because they contain no searchable content, and don't explain why someone should "try this". We make an effort here to be a resource for knowledge.
1

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.

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.