23

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.

3
  • where's the json being generated? Has inconsistent patterns within albums. Fisrt album has no array in it, other two do. Would have to remap data before passing to angular that way Commented Nov 7, 2013 at 1:57
  • I generated typing it. But a php script will generate it later. Everytime i use JsonLint to validate my Json, so ignore this erros please. THanks! Commented Nov 7, 2013 at 20:00
  • well structure of json is far from ideal. It's not about being valid...it's that should use arrays of objects...will make it a lot easier setting up angular Commented Nov 7, 2013 at 20:08

4 Answers 4

16

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>
Sign up to request clarification or add additional context in comments.

Comments

8

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

Comments

6

Check Plunker link

Answer to your question "how will i select on this nested json?"

$.each(data.artists, function(index, element){
  $.each(this.albums, function(index, element){
    $scope.albums.push(element);
  });
});

Answer to your question "how will i filter those artists with a text field?"

<input ng-model="searchText.artistName">

<ul ng-repeat="album in albums | filter:searchText">
    <li>{{album.title}}</li>
</ul>

1 Comment

Thanks a lot! Your example was very enlightening. I'm very newbie on this and your answer was awesome!
0
<ul ng-repeat="artist in artists">
    <li>
        <p>{{artist.name}}</p> 

        <ul ng-repeat="(key,val) in artist.albums">

            <li>{{key}} - {{val}}</li>

        </ul> 
    </li>
</ul>

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.