javascript - access ng-resource in function through $scope causes infinite loop -


i have rails app , access 2 models through json api using ng-resource.

in template display list of first model "orders":

<li ng-repeat="order in orders">   order {{order.id}}:    product: {{showproduct(order.product_id)}} </li> 

each "order" contains product_id. access second model ("products") , display inside ng-repeat correct "product" id product_id of corresponding "order".

to achieve thought of using function showproduct() , use order.product_id argument. when causes infinite loop keeps making requests database.

here important part of app.js

var app = angular.module('shop', ['ngresource']);  app.factory('models', ['$resource', function($resource){   var orders_model = $resource("/orders/:id.json", {id: "@id"}, {update: {method: "put"}});   var products_model = $resource("/products/:id.json", {id: "@id"}, {update: {method: "put"}});    var o = {      orders: orders_model,     products: products_model   };   return o; }]);  app.controller('ordersctrl', ['$scope', 'models', function($scope, models){   $scope.orders = models.orders.query();    $scope.showproduct = function(product_id){     return models.products.get({id: product_id});   }; }]) 

these errors in console (which make sense since it's infinite loop):

error: [$rootscope:infdig] 10 $digest() iterations reached. aborting! watchers fired in last 5 iterations: []  uncaught error: [$rootscope:infdig] 10 $digest() iterations reached. aborting! watchers fired in last 5 iterations: [] 

the request in rails console seems fine. maybe i'm trying think more complicated need to.

yes because have showproduct in view, function called on every digest, returning each time different promise breaks:

  • you create server requests several times per digest
  • each request different other
  • 10 iterations made until 2 values equal or throws exception

i suggest do:

models.orders.query().$promise   .then(function(orders){     $scope.orders = orders;     //using lodash here, recommend use     _.each(orders, function(order){       models.products.get({id: order.product_id }).$promise         .then(function(product){           order.product = product;         })     });   }); 

and in view:

<li ng-repeat="order in orders">   order {{order.id}}:    product: {{order.product}} </li> 

but using code trigger 1 query each order quite bad: n+1 anti pattern.

2 solutions:

  • have order include product data directly
  • have 1 single request product ids

Comments

Popular posts from this blog

javascript - Chart.js (Radar Chart) different scaleLineColor for each scaleLine -

apache - Error with PHP mail(): Multiple or malformed newlines found in additional_header -

java - Android – MapFragment overlay button shadow, just like MyLocation button -