Search code examples
javascriptangularjsangular-factory

How to make the updated value in factory to be shown in DOM


Please look at the example here. I want the dom to updated after each second.

var myApp = angular.module("myApp", ['ui.bootstrap']);
myApp.factory("productCountFactory", function() {
  var total = 0
  setInterval(function checkItems(){
            total++;
        }, 1000);

    var add =function(){
      total++
    }
  return {
    totalProducts: function(){
      return total
    },
    add: add
  };
});

Currently it updates only when I click on add button.

This is just an example. What I want to achieve is, after timeout, I want to remove certain elements from an array and display remaining values using ng-repeat. Any help would be great.


Solution

  • You will achieve this when using the $interval service instead the native setInterval()

    // Code goes here
    
    var myApp = angular.module("myApp", ['ui.bootstrap']);
    myApp.factory("productCountFactory", function($interval) {
      var total = 0
      $interval(function checkItems() {
        total++;
      }, 1000);
    
      var add = function() {
        total++
      }
      return {
        totalProducts: function() {
          return total
        },
        add: add
      };
    });
    myApp.controller("welcomeContoller", function($scope, productCountFactory) {
      $scope.productCountFactory = productCountFactory;
    });
    
    myApp.controller("productController", function($scope, productCountFactory) {
      $scope.addProduct = function() {
        console.log(productCountFactory.totalProducts());
        productCountFactory.add();
        console.log(productCountFactory.totalProducts());
      };
    });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script data-require="ui-bootstrap@*" data-semver="1.1.1" src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-1.1.1.js"></script>
    <link data-require="[email protected]" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
    
    <body ng-app="myApp">
      <div ng-controller="welcomeContoller">
        {{productCountFactory.totalProducts()}}
      </div>
      <hr>
      <div ng-controller="productController">
        <div class="addRemoveCart">
          <button ng-click="removeProduct()">Remove</button>
          <button ng-click="addProduct(1)">Add</button>
        </div>
      </div>
    </body>

    But note that:

    source

    Intervals created by this service must be explicitly destroyed when you are finished with them. In particular they are not automatically destroyed when a controller's scope or a directive's element are destroyed. You should take this into consideration and make sure to always cancel the interval at the appropriate moment.

    You can make sure that the interval is destroyed with something like:

    var myInterval = $interval(someFunction);
    
    $scope.$on('$destroy', function() {
        if (angular.isDefined(myInterval)) {
            $interval.cancel(myInterval);
            myInterval = undefined;
        }
    });