Dan Rockstone
Dan Rockstone

Reputation: 33

AngularJs: ng-repeat not updating with list from service

app.js:

var app = angular.module('myApp',
[]);

app.controller('ExampleController', ['$scope', 'myService', function($scope, myService) {
  $scope.titles=myService.list;
  $scope.controllerFunction = function() {
    myService.list.push("bla");
  };
}]);

app.service('myService',[ function(){

  return {
    list: ['test', 'test2', 'test3']
  };
}]);

app.directive('myDirective',['myService', '$compile', function(myService, $compile) {

  return {
    scope: true,
    link: function($scope, $element, attrs, ctrl, $transclude) {

      $scope.list = myService.list;


    },
    template: '<div ng-repeat="item in list">{{item}}</div>{{list}}'

  };
}]);

index.html:

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <link rel="stylesheet" href="style.css">
    <script data-semver="1.4.3" src="https://code.angularjs.org/1.4.3/angular.js" data-require="[email protected]"></script>
    <script src="app.js"></script>
  </head>

  <body>
    <div ng-controller="ExampleController">
      <my-directive></my-directive>

      <button ng-click="controllerFunction()">add</button>
    </div>
  </body>

</html>

A Plunker of it: http://plnkr.co/edit/frtVJlXvRAmlYLUW7BXL?p=preview

When I add an item via the add button, the ng-repeat only updates the first time. The list itself gets updated, as can be seen by behind the ng-repeat, where I just print {{list}}, but the ng-repeat seems to get stuck.

I am aware of workarounds and am using an observer pattern as of now, but I feel that this behaviour is not intended, so I would like to know if I am simply missing something or if this is a bug.

Upvotes: 0

Views: 775

Answers (1)

Joe Pontani
Joe Pontani

Reputation: 451

Check your console messages and you'll see why. ng-repeat requires a unique identifier in determining where each item is bound. By adding multiple 'bla' strings to your list, you are adding duplicates that the directive doesn't know how to track changes to a specific item.

Use the track by syntax, and the issue will be fixed.

<div ng-repeat="item in list track by $index">{{item}}</div>{{list}}

http://plnkr.co/edit/Tog0IviB68dcahKYvfpe

Upvotes: 4

Related Questions