Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing nested JSON with AngularJS

Tags:

I'm trying to make and mobile webapp with angular.js, hammer.js and topcoat.

I'm having some trouble on displaying data from a Json file like this one:

{ "version": "1", "artists": {     "artist1": {         "name": "artist1name",         "jpeg": "../img/artist/artist1.jpg",         "albums": {             "album1": {                 "type": "cd",                 "title": "titlealbum1",                 "subtitle": "subtitlealbum1",                 "jpeg": "../img/album1.jpg",                 "price": "12.00",                 "anystring1": "anystring1album1",                 "anystring2": "anystring2album1"             },             "album2": [{                 "type": "cd",                 "title": "titlealbum2",                 "subtitle": "subtitlealbum2",                 "jpeg": "../img/album2.jpg",                 "price": "12.00",                 "anystring1": "anystring1album2",                 "anystring2": "anystring2album2"             }],             "album3": [{                 "type": "cd",                 "title": "titlealbum3",                 "subtitle": "subtitlealbum3",                 "jpeg": "../img/album3.jpg",                 "price": "13.00",                 "anystring1": "anystring1album3",                 "anystring2": "anystring2album3"             }]         }     },     "artist2": {         "name": "artist2name",         "jpeg": "../img/artist/artist2.jpg", 

My js file is like this:

angular.module('list', []) function ListCtrl ($scope, $http) { $http({method: 'GET', url: 'json/json_price_1.json'}).success(function(data) { $scope.artists = data.artists; // response data  $scope.albums = data.artists.albums; /this is where im getting trouble });         }; 

My HTML file is like this:

<body ng-app="list">  <h3>Titulos</h3>  <div ng-controller="ListCtrl"> <ul ng-repeat="artist in artists">         <li >{{artist.name}}</li>      </ul> </div>  <div ng-controller="ListCtrl"> <ul ng-repeat="album in albums">         <li >{{album.title}}</li>  //not working here.       </ul> </div> 

I want to display all albums and if my user select an specific artist I want to filter those albums. The question here is how will I select on this nested json. BTW, the artist.name is displaying correctly.

Second question is, how will I filter those artists with a text field.

like image 265
scarface13 Avatar asked Nov 06 '13 23:11

scarface13


2 Answers

I suggest something like this:

$http({method: 'GET', url: 'json/json_price_1.json'}).success(function(data) {     $scope.artists = [];     angular.forEach(data.artists, function(value, key) {         $scope.artists.push(value);     });     $scope.isVisible = function(name){         return true;// return false to hide this artist's albums     }; }); 

And then:

<div ng-controller="ListCtrl">     <ul>         <li ng-repeat="artist in artists">{{artist.name}}</li>     </ul>     <ul ng-repeat="artist in artists" ng-show="isVisible(artist.name)">         <li ng-repeat="album in artist.albums">{{album.title}}</li>     </ul> </div> 
like image 179
Adam Avatar answered Oct 16 '22 15:10

Adam


All your problems start with your JSON. I recommend you to simplify your JSON and make each Artist and Album an Object and Artists and Albums arrays of objects.

Try this one:

 {   "version": "1",   "artists": [     {       "name": "artist1name",       "jpeg": "../img/artist/artist1.jpg",       "albums": [         {           "type": "cd",           "title": "titlealbum1",           "subtitle": "subtitlealbum1",           "jpeg": "../img/album1.jpg",           "price": "12.00",           "anystring1": "anystring1album1",           "anystring2": "anystring2album1"         },         {           "type": "cd",           "title": "titlealbum2",           "subtitle": "subtitlealbum2",           "jpeg": "../img/album2.jpg",           "price": "12.00",           "anystring1": "anystring1album2",           "anystring2": "anystring2album2"         },         {           "type": "cd",           "title": "titlealbum3",           "subtitle": "subtitlealbum3",           "jpeg": "../img/album3.jpg",           "price": "13.00",           "anystring1": "anystring1album3",           "anystring2": "anystring2album3"         }       ]     },     {       "name": "artist2name",       "jpeg": "../img/artist/artist2.jpg",       "albums": []     }   ] }  

An Array can be empty as in my example (artist2 has no album assigned).

You have also wrong asignment in your ListCtrl, you cannot assign and display albums until you know the correct Artist. If you want to diplay all albums of all artists, you need to iterate through all artists.

Example controller:

 angular.module('list', []);  function ListCtrl($scope, $http) {   $http({     method: 'GET',     url: 'json_price_1.json'   }).success(function(data) {     $scope.artists = data.artists; // response data     $scope.albums = [];     angular.forEach(data.artists, function(artist, index) {       angular.forEach(artist.albums, function(album, index){         $scope.albums.push(album);       });     });   }); }

Here is modified Plunkr based on jessie example: http://plnkr.co/edit/zkUqrPjlDYhVeNEZY1YR?p=preview

like image 27
ivoszz Avatar answered Oct 16 '22 14:10

ivoszz