2

I am trying to display all the books of some series. I used nested ng-repeat and it works well. However, due to some recent changes on layout requirements, I cannot use nested ng-repeat (I want a single list of books). I would expect something like below

<ul>
    <li>book1 of series1</li>
    <li>book 2 of series 1</li>
    <li>book1 of series 2</li>
    <li>book2 of series 2</li> 
    <li>book1 of series 3</li>
    <li>book2 of series 3</li>
</ul>

Is there a way to do it with 1 ng-repeat? Or with other approach? (I.e. Array)

Data

var data = {
    "records": [
        {
            "name": "Spectrum Series",
            "seriesid": "SpectrumSeries",
            "book": [
                {
                    "name": "White Curse",
                    "bookid": "WhiteCurse",
                    "image": "book1"                    
                },
                {
                    "name": "Blue Fox",
                    "bookid": "BlueFox",
                    "image": "book2"                   
                }
            ]
        }

… other series
 ]
};

Controller

$scope.serieslist = data.records;

HTML

    <div ng-repeat="series in serieslist">
        <ul ng-repeat="book in series.book">            
            <li>                  
                <div>{{series.name}}</div>
                <div>{{book.name}}</div>                    
            </li>            
        </ul>
    </div>
4
  • How would you like the result?. ie Commented Jun 11, 2015 at 12:52
  • Please provide your desired HTML structure (non-nested). If I understood you correctly, you will need to use ng-repeat-start and ng-repeat-end in order to have a flat HTML structure. But cannot write a concrete answer without your new HTML structure. Commented Jun 11, 2015 at 12:52
  • how about this<div ng-repeat="series in serieslist"> <li> <div>{{series.name}}</div> <div>{{series.book[0].name}}</div> </li> </ul> </div> Commented Jun 11, 2015 at 12:54
  • Here is what I expected <ul><li>book1 of series1</li><li>book 2 of series 1</li><li>book1 of series 2</li><li>book2 of series 2</li><li>book1 of series 3</li><li>book2 of series 3</li></ul> Commented Jun 11, 2015 at 12:56

5 Answers 5

1

Since you want only one list of books, try this

<div ng-repeat="series in serieslist">
        <li>                  
            <div>{{series.name}}</div>
            <div>{{series.book[0].name}}</div>
        </li>            
    </ul>
</div>

Hope this helps!!!

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

1 Comment

Thank you for your answer. I have just tried it and it only display the series name and the name of the first book of each series
1

You need to flatten the array first in your controller into an array with series number and book number, and then use the ng-repeat on the new array.

To do that you can use two angular.forEach on the original array (one for the series and other for the books in each series).

$scope.serieslist = [];
    var seriesNumber = 1;
    angular.forEach(data.records, function(series) {
        var bookNumber = 1;
        angular.forEach(series.book, function(book) {
            $scope.serieslist.push(
                {
                    seriesNumber: seriesNumber,
                    bookNumber: bookNumber++,
                    seriesid: series.seriesid,
                    name: series.name,
                    book: book
                });
        });
        seriesNumber++;
    });

Here's a plnkr

1 Comment

Thank you for your great answer. It work flawlessly.
0

Working JS fiddle

Just replace element of DOM for use nested ng-repeat

<div ng-app='Your app'>
     <div ng-controller='Your controlelr'>
        <ul ng-repeat="series in serieslist">            
            {{series.name}} 
            <li ng-repeat="book in series.book" >{{ book.name }}</li>
        </ul>
      </div>
 </div>

or

 <div ng-app='myApp'>
     <div ng-controller='Home'>
        <ul ng-repeat="series in serieslist">            
            <li ng-repeat="book in series.book" >{{ book.name }} of {{series.name}}</li>
        </ul>
      </div>
 </div>

for this result

2 Comments

Thank you for your answer. This looks like my current approach. My question is how to do it with only 1 ng-repeat because nested ng-repeat will generates multiple lists which makes it very difficult to implement line wrap
Maybe with angular.foreach in controller but it's not possible for me with one ng-repeat, you need to loop in any case because there are two arrays
0

You can use something like underscorejs to produce a flattened version of your list and then ng-repeat over that. For how you might do that, refer to Karl's answer on this stackoverflow question here: How to flatten with ng-repeat

1 Comment

I very appreciate your answer. This is what I wanted. I used forEach of Angular instead of for loop and it works.
0

Controller

$scope.serieslist = data.records;
    $scope.flatbooklist = [];
    angular.forEach($scope.serieslist, function (series)
    {
        angular.forEach(series.book, function (book)
        {
            $scope.flatbooklist.push({seriesname: series.name, seriesid: series.seriesid, bookname: book.name, bookid: book.bookid, bookimage: book.image});
        });
    });

HTML

<ul ng-repeat="book in flatbooklist">
    <li>
        <div>{{book.seriesname}}</div>
        <div>{{book.bookname}}</div>
    </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.