0

I've tried to create a very simple example of the issue I'm having with AngularJS. I've got a simple scope called testScope. I also have 2 other scopes (grouped1 and grouped2) that are derived from testScope that have been altered using a grouping function found in UnderscoreJs.

script.js

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

app.controller('mainCtrl', function($scope) {
  $scope.testScope = { 
    test1: {
      data: [
        {
          field1: 'blah',
          field2: 'blah blah'
        },
        {
          field1: 'test',
          field2: 'test test'
        }
     ]
    }
  };

  $scope.createEntry = function(newEntry) {
    $scope.test1.data.push({field1: newEntry.field1, field2: newEntry.field2});
  };

  $scope.test1 = $scope.testScope['test1'];
  $scope.grouped1 = _.groupBy($scope.test1, 'field1');
  $scope.grouped2 = _.groupBy($scope.test1.data, 'field1');
});

index.html

<body ng-app="testScope" ng-controller="mainCtrl">
  <form ng-submit="createEntry(newEntry)">
    Field1: <input type="text" ng-model="newEntry.field1" />
    Field2: <input type="text" ng-model="newEntry.field2" />
    <input type="submit" />
  </form>

  data
  <div> {{ test1 }} </div><br>

  grouped1
  <div>{{ grouped1 }}</div><br>

  grouped2
  <div>{{ grouped2 }}</div>
</body>

The problem is that when I modify my scope (using the form), test1 and grouped1 will update but grouped2 will not. Why doesn't grouped2 update and how do I get grouped2 to update when the scope changes?

Please see my example: http://plnkr.co/edit/IN8lADekDBxDp1CNf8VG?p=preview

Lydon
  • 2,942
  • 4
  • 25
  • 29
  • Are you sure you're meaning to do: `$scope.grouped2 = _.groupBy($scope.test1.data, 'field1');` isntead of `$scope.grouped2 = _.groupBy($scope.test1, 'field1');` – JGibbers Jun 18 '14 at 14:47
  • Yes. I'm already doing `_.groupBy($scope.test1, 'field1')` in `$scope.grouped1`. I'm trying to determine why one works but the other doesn't even though they are so similar. – Lydon Jun 18 '14 at 14:57
  • If I were to guess, the reference to $scope.test1.data is changing when you push each time. The reference is what $scope checks each time, so if that changes, the scope binding doesn't work as intended. See [here](http://stackoverflow.com/questions/18568373/angularjs-factory-property-isnt-being-updated-in-scope-when-not-using-push) – JGibbers Jun 18 '14 at 15:04
  • It might be that one of your _.groupBy's is creating a new copy of your object (thus not referencing the original object, and not updating with it) and the other groupBy returns just a reference to the original object – Rodik Jun 18 '14 at 15:07

1 Answers1

0

the reference that .groupBy($scope.test1.data, 'field1') creates changes each time $scope.test1.data changes1. Since $scope works based off of the reference, changing that allows the data to become stale or outdated.

To fix this, you can simply wrap the scope in a function. Such as this:

$scope.grouped2 = function() {return _.groupBy($scope.test1.data, 'field1');};

And then just change your reference in your html like so:

grouped2
<div>{{ grouped2() }}</div>

plunkr: here

JGibbers
  • 248
  • 3
  • 13
  • When I do `_.groupBy($scope.test1, 'field1')`, this creates a new reference each time doesn't it? So it should work the same as `.groupBy($scope.test1.data, 'field1')`, no? Anyone know the reason why they are treated differently? – Lydon Jun 19 '14 at 01:35