6

I have a list of items that I'm displaying with ng-repeat. I want to add a filter to show/hide archived items.

I have added a checkbox:

<input type="checkbox" ng-model="queryFilter.archived">Show archived messages

In my controller I have this:

$scope.queryFilter = {
    archived: false
};

My list of items is displayed in a table. I've tried the following:

<tr ng-repeat="message in messages | filter : queryFilter">

<tr ng-repeat="message in messages | filter : { archived: queryFilter.archived }">

<tr ng-repeat="message in messages | filter : queryFilter track by $index">

I get this error:

Error: [filter:notarray]

Expected array but received: {}

The filtering does work but I want to know why I am getting the error.

1
  • What is your massage structure? this "archive: true/false" doesn't mean anything Commented May 22, 2016 at 14:05

4 Answers 4

8

I had initialised messages as an object.

Changing $scope.messages = {}; to $scope.messages = []; made the error go away.

Sign up to request clarification or add additional context in comments.

1 Comment

Very cool! Of all the options I tried, just this small tweak made those errors go away. I'd even gone to the length of using a custom function to map the object into an array, but then my object had nested objects and things started getting out of hands.
5

Your messages must be containing the data in Object form not in the Array form.

That is why this error is being thrown. Check the doc https://docs.angularjs.org/error/filter/notarray

From the docs:

Filter must be used with an array so a subset of items can be returned. The array can be initialized asynchronously and therefore null or undefined won't throw this error.

So make sure, your $scope.messages containing data in array form not in the Object form.

Comments

5

The track by $ index makes angular syntax incorrect, since it is directly positioned behind the filter instruction. Try moving it behind the repeat statement so there is a clear separation between the track by and filter statements.

<tr ng-repeat="message in messages | filter : queryFilter track by $index">

Comments

4

queryfilter is an object not an array. So apply the ng-repeat on queryfilter as given below <tr ng-repeat = "message in messages | filter : queryFilter track by $index">

if queryfilter is array then simply use

<tr ng-repeat = "message in messages | filter : queryFilter">

track by $index is necessary whenever we loop the object

1 Comment

The thing that has messed me up every time trying to filter, is that the filter needs to go BEFORE the track by, otherwise the filter gets applied to the $index variable, which results in the "not an array" error. Had to dig into the angular code to see what was going on. Hope this helps someone else from tearing their hair out...

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.