Reputation: 1779
I have the following piece of code.
https://plnkr.co/edit/Tt7sWW06GG08tdJu72Fg?p=preview. Please expand the window fully to see the whole view.
I have categories
and sub-categories
to display in a navbar as shown in the above plunkr. Each category has services/sub-categories to display.
I am using 2 nested ng-repeats
and the inner one is using the value from the parent iteration of ng-repeat
. I have attached a function getServicesByCategory
to the inner ng-repeat
that calls getServicesByCategory
from the DocumentsFactory
and resolves the promise
to return data in an array object subcategories
, which eventually should get iterated by inner ng-repeat
.
The categories are displaying fine but the sub-categories are not.
There are 2 problems with this.
1). The subcategories are being shown the same for every category, and the ones being shown belong to the last category in the outer ng-repeat iteration i.e Utility Services
. Instead each category should shows it's own sub-categories.
2). The console shows multiple errors of infinite digest cycle
aborting due to attempts exceeding than 10 with these errors http://errors.angularjs.org/1.5.6/$rootScope/infdig?p0=10&p1=%5B%5D repeatedly in console. The method getServicesByCategory
is being called in an infinite loop triggering multiple digest cycles.
Seems like a simple category problem complicated by Angular's dirty checking
and digest cycles
.
I read multiple threads and posts suggesting to not return a new object inside the function associated with ng-repeat which I am not. I am returning the reference of subcategories
.
The inner
ng-repeat is dependent upon the data from outer
one. Binding a function to ng-repeat was only option for me. Is this the right approach? The API's to fetch categories and subcategories are different and I dont have the flexibility to change them. I have been unable to come up with a solution. Just want to right sub-categories against each category.
Any help will be highly appreciated!
Note: Open the view in full window to see the navbar on the left.
Upvotes: 0
Views: 525
Reputation: 3440
The solution here is to get all the data you need and create an array of categories, each one containing its own sub categories. And use this object in the nested ng-repeats
.
Please check my updated version of your plunker:
https://plnkr.co/edit/BaHOcI4Qa8t5CkbshyCX
As you can see, I use:
ng-repeat="category in documents.categories"
In the outer ng-repeat
and:
ng-repeat="service in category.subCategories"
In the inner one.
In the Controller I build the category.subCategories
in the following way:
documentsFactory
.getCategories() // Get categories
.then(function(response) { // Extract them from the response
return response.data.subCategory;
})
.then(getSubcategories) // For every catgory, get its own subcategory
.then(function(categories) { // Add categories to the $scope
self.categories = categories;
});
Where getSubcategories
is:
function getSubcategories(categories) {
console.log(categories)
var retrievSubcategories = categories.map(function(category) { // Create a promise to get the subcategories for every category
return documentsFactory
.getServicesByCategory(category.name) // Get the subcategories for the given category
.then(function(response) {
category.subCategories = response.data.documents; // Add subgategories to the category
return category;
});
});
return $q.all(retrievSubcategories) // Return a promise resolve only when all the subcategories for every category are retrieved
}
Upvotes: 1