0

So I have a list of news articles, and I need them to be filtered but server side not client side.

The way I'm filtering is by having a dropdown list that users click on to filter the articles like so:

<ul>
   <li ng-repeat="category in categories">
       <span href="" ng-click="getFilteredArticles(category.id)">{{category.title}}</span>
   </li>
 </ul>

and the articles are populated via an ng-repeat like so

<ul infinite-scroll="addPosts()" infinite-scroll-distance="0" infinite-scroll-disabled="stopScrolling" class="c-news">
    <li ng-repeat="post in posts" class="c-news__item" ng-click="selectPost(post)">
        <!-- Omitted some code for the sake of brevity -->
     </li>
 </ul>

The getFilteredArticles method looks like this

 $scope.getFilteredArticles = function (categoryId) {

        var posts = $scope.posts;

        posts.forEach( (object) => {
            if ( object[Categories.Id] === categoryId ) {
                $scope.filteredArticles.push(object);
            }
        });

        console.log($scope.filteredArticles);
    }

A typical JSON object that I'm pulling through looks like this

{  
     "Title":"Test Title",
     "Summary":"",
     "PublishedDate":"2016-10-17T09:42:00",
     "Author":{  
        "Id":"480586a5-2169-e611-9426-00155d502902",
        "FirstName":"TestFirst",
        "LastName":"TestSecond",
        "Email":"[email protected]"
     },
     "Id":99,
     "StatusName":"Published",
     "Status":2,
     "Categories":[  
        {  
           "Id":1,
           "Name":"Category 1",
           "ArticleCount":31,
           "UnpublishedArticleCount":1
        },
        {  
           "Id":2,
           "Name":"Category 2",
           "ArticleCount":19,
           "UnpublishedArticleCount":0
        }
     ],
     "AttachmentCount":0,
     "FilesAwaitingCheckIn":0
  }

What I'd like to happen is when the user clicks one of the filter choices, for the list to then filter to the clicked choice. I've got this far but then I'm getting a ReferenceError: Categories is not defined.

I based my getFilteredArticles() code from another Stack question which can be found here.

I'm aware of being able to just filter the ng-repeat however my manager does not want to go that route and would rather filter server side due to the amount of posts that we may have.

Any ideas?

EDIT Here's what's inside $scope.posts array

10
  • 1
    If Categories is a property of posts, you should define it like this object["Categories"]["Id"] === categoryId Commented Oct 20, 2016 at 9:36
  • Thanks for that Nishant, that has got me past that error. Now the console.log is just spitting out an empty array. Could it be due to each category id being inside a separate object within the Categories object? Commented Oct 20, 2016 at 9:47
  • I guess the if condition is not being met. You have used a strict check ===. Check if both the types are same. There is a difference between "2" and 2. Also debug the values inside the loop before if condition Commented Oct 20, 2016 at 9:57
  • Thanks for your prompt reply, so I console.log(object["Categories"]["id"]); this spits out an (20) undefined message. However when I remove ["id"] I get each objects categories object spat out. I'm guessing there's something wrong with traversing to id within the categories object? Apologies if I'm missing something basic, I'm much more of a UI Designer than developer/programmer :) Commented Oct 20, 2016 at 10:13
  • Sorry for late reply. Can you update your question with posts array? Commented Oct 20, 2016 at 10:45

1 Answer 1

1

As Categories is an array you need to loop through that array to get Id's

Your loop should be similar to this

$scope.getFilteredArticles = function (categoryId) {

        for(var i=0;i<$scope.posts.length;i++)
        {
            for(var j=0;j<$scope.posts[i]["Categories"].length;j++)
          {
            if($scope.posts[i]["Categories"][j]["Id"] == categoryId)
                $scope.filteredArticles.push($scope.posts[i])
          }
        }
        console.log(JSON.stringify($scope.filteredArticles));
    };
Sign up to request clarification or add additional context in comments.

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.