Search code examples
jsonangularjsangularjs-ng-repeatangularjs-routing

Filter JSON data based on current URL route


The problem

I'm trying to filter json data and display only a portion of it on an Angular page, based on the page's current URL.

In detail

I have a list of 100 JSON objects, and each one looks like this:

{
  "name": "Evangeline Perreault",
  "age_1": 1,
  "total_age": 1,
  "photo_small": "img/400/001_400.jpg",
  "photo_medium": "img/800/001_800.jpg",
  "photo_large": "img/1200/001_1200.jpg",
  "photo_extralarge": "img/1600/001_1600.jpg",
  "video": 67443664,
  "id": 1,
  "quote": "test quote here and here",
  "type": 1
},

The 'type' attribute is what I want to use to filter out the subsets of my data. With that in mind, I tried to setup my URL structure to tie the type attribute here to my url. Here is my route:

angular.module('100_Ages', ['mydirectives', 'ngResponsiveImages']).
    config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/100_Ages/nav/:personType', {templateUrl: 'partials/person-list.html', controller: NavListCtrl}).
        otherwise({redirectTo: '/100_Ages'});
    }]);

So, I have pointed the route to the 'type' field in my JSON and I tried writing a controller to tie the two together.

function NavListCtrl($scope, $routeParams, $http) {
  $http.get('person.json').success(function(data) {
  angular.forEach(data, function(person) {
          if (person.type == $routeParams.personType) 
            $scope.person = person;
        });
  });
}

And here is my partial template:

<div class="nav_outer"><img class="nav_img" ng-src="{{person.photo_small}}" ng-alt="{{person.name}}" /></div>

I expected this to display all the matching images for the URL type I'm on. So, if I'm on "/100_Ages/nav/3", I expected all the images (roughly 10 pictures) from the objects with a type of "3" to display. However, it only displayed the last object with a type of "3".

So, I tried an ng-repeat like so:

<div class="nav_outer" ng-repeat="person in persons"><img class="nav_img" ng-src="{{person.photo_small}}" ng-alt="{{person.name}}" /></div>

I expected that to loop through and show all the matching images, but that made nothing at all show up.

I think my problem has to do with the angular.forEach, but I'm not sure how else to tie my JSON type to the page's typeid.

Thanks for any suggestions.


Solution

  • The ng-repeat should work if you push each item into an array. (Also, you are referring to a 'persons' object in the ng-repeat, which doesn't exist according to code provided). So, try this:

    $http.get('person.json').success(function(data) {
        $scope.persons = [];
        angular.forEach(data, function(person) {
            if (person.type == $routeParams.personType) 
                $scope.persons.push(person);
                // or alternatively - this.push(person), with the optional 3rd param of $scope.persons (I don't really understand that, but whatever...)
        });
    });
    

    Now with the array populated, your ng-repeat="person in persons" should work.

    UPDATE:

    If the success object was already an array of objects, then just set the scope object to the array - no need to iterate through them:

    $http.get('person.json').success(function(data) {
        $scope.persons = data;    
    })