AngularJS factory property isn't being updated in $scope when not using push()

All we need is an easy explanation of the problem, so here it is.

I have a factory that is retrieving the data from an external source. As soon as i get the data, i use a second factory to filter it by a certain criteria.

The factory property is assigned to scope.

Now when i do this in my factory, it doesn’t update the scope: = [{id:1,name:'foo'}]; // doesn't work

therefor also the filterin in a second factory doesn’t work = Filter.filter(); // doesn't work

while this works:{id:1,name:'foo'}); // works

Does anyone have an idea if this is intended and why it is like this, and how to solve it?

Full Sample plus plunkr

app.factory('Foo',function(Filter) {
  var factory = {
    getDataForFoo:function() { = Filter.filter(); // doesn't work
      // = [{id:1,name:'foo'},{id:1,name:'foo'}]; // doesn't work
      //{id:1,name:'foo'}); // works
  return factory;

app.factory('Filter',function() {
  var factory = {
    filter:function() {
      var arr = [];
      return arr;
  return factory;

app.controller('MainCtrl', function($scope,Foo) {
  $scope.test = 'running';
  $ =;

  $ = Foo.getDataForFoo;


How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

The problem is that your factory replace the reference to When your scope is initialized, $ holds a reference to an array (empty). When you call Foo.getDataForFoo, it internally changes the reference to but your scope still hold a reference to the previous array. This is why using push works as it doesn’t change the array reference, but the array content.

There are a few ways to fix this. Without going in all the different options, the easiest one is to wrap your $ in a function, returning This way, Angular will detect a reference change in a digest cycle and will update the view accordingly.

app.controller('MainCtrl', function($scope,Foo) {
  $scope.test = 'running';
  $ = function() { return };

  $ = Foo.getDataForFoo

// And in the view (the relevant part)

<ul ng-repeat="elem in foo()">
  <li>{{}} {{}}</li>
<a href="" ng-click=" rel="nofollow noreferrer noopener"click()">add</a>

Method 2

@Simon-Belanger answer is correct and he presents a viable solution.

Another option would be to just empty the array and push new items into it (e.g. for a refresh event), rather than resetting the reference by assigning a new array to it. You can truncate an array by assigning to the length: myArray.length = 0 and then you can iterate over the new collection to populate new entries via array.push()

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply