Reputation: 657
I have the following relationship: Categories <---> Products (with a 1-N cardinality)
This is the ng-repeat directive in the html table
<tr ng-repeat="category in categories">
<td>{{category.name}}</td>
<td>{{products[category.id]}}</td>
</tr>
So what I need to do is when every time the repeat list a category, this category will be send immediately to the getAllProductsByCategory() function and then the $http service will get all the products that belong to this specific category.
I tried to use the ng-init directive in order to execute the function but I think it's not the correct way to use it. Is there a better way to do it?
<tr ng-repeat="category in categories" ng-init="getAllProductsByCategory(category)">
<td>{{category.name}}</td>
<td>{{products[category.id]}}</td>
</tr>
And this is the function that will get all the products by category
$scope.getAllProductsByCategory = function(category){
$http("getAlProductsByCategory"+category.id){
.success(function (data, status, headers, config) {
$scope.products[category.id] = data;
})
.error(function (data, status, header, config){
$log.error("Error");
});
}
Upvotes: 0
Views: 758
Reputation: 48948
I don't know how to split an array in the controller in order to pass every object to the getAllProductsByCategory(category)
I don't recommend using ng-init
to make calls to asynchronous APIs. In a model-view-whatever architechure, the model should drive the view. The view should not drive the model. The view can collect user input events for the controller. The controller can then use those events to update the model, using asynchronous APIs if necessary.
In this case the list of categories probably came from an asynch API, then the products for each category need to come from an asynch API. This can accomplished be chaining promises.
First create a categories promise:
var categoriesPromise = $http.get(categoriesUrl)
.then(function (response) {
var categories = response.data;
$scope.categories = categories;
//return to chain categories
return categories;
}).catch(function (error) {
console.log("ERROR: ", error.status);
//throw to chain rejection
throw error;
});
Now chain from that promise:
$scope.products = {};
var productsPromise = categoriesPromise.then(function(categories) {
var promiseHash = {};
categories.foreach(function(c) {
promiseHash[c.id] = getProductsByCategory(c)
.then(function(products) {
$scope.products[c.id] = products;
//return data for chaining
return products;
});
});
//return $q.all promise for chaining
return $q.all(promiseHash);
});
For more information, see
Upvotes: 1
Reputation: 1337
ng-init will be execute only once at the beginning not for every category. I think what you're trying to do is this:
<tr ng-repeat="category in categories">
<td>{{category.name}}</td>
<td>{{products[category.id]}}</td>
<script type="text/javascript">
getAllProductsByCategory({{category}});
</script>
</tr>
but there are easier ways to do this, instead of calling once for each category, which is bad from a performance point of view, like creating an array of categories and calling them only once in the controller having them ready for whatever you want to use them.
Upvotes: 0