Search code examples
angularjsangularjs-ng-repeatangularjs-service

AngularJS - Ng-Repeat does not update


I am working on a web store using Angular and am trying to clean the code using a service. I would like the service to load a list of items from a REST api and perform functions on those items across a variety of controllers. My problem occurs when I try to populate an ng-repeat statement with the data returned from the REST call - the list is never populated with the items that are fetched. Previously I was using $scope and $apply to ensure that my DOM was updated when the data was returned - is there something similar that I can do within the service?

The service

'use strict';
var serv = angular.module('serv', []);
serv.factory('shopService', function() {
    //create the shop client as service varible
    var client = window.ShopifyBuy.buildClient({
        domain: 'xxxxxxx.myshopify.com',
        storefrontAccessToken: 'xxxxxxxxxxxxxxxxx'
    });
    var products = [];
    client.product.fetchAll().then((products_complete) => {
        //do things and get the products ready
        products.push(item);
    });

    return {
        products: products
    }
});

The controller

'use strict';
var serviceApp = angular.module('serviceApp', ['serv']);
serviceApp.controller('CartController', ['shopService', function CartController(shopService) {
    //create a reference to the service variable
    this.products = shopService.products;
}]);

And the HTML

<body>
    <div ng-app="serviceApp" ng-controller="CartController as cart">
        <ul>
            <li ng-repeat="product in cart.products">
                <div> {{ product.title }} </div>
            </li>
        </ul>
    </div>
</body>

Any help is appreciated.


Solution

  • You can make sure the promise finishes running before assigning the products in the controller and avoid running the fetchAll more than once. You can change the service:

    serv.factory('shopService', function($q) {
        //create the shop client as service varible
        var client = window.ShopifyBuy.buildClient({
            domain: 'xxxxxxx.myshopify.com',
            storefrontAccessToken: 'xxxxxxxxxxxxxxxxx'
        });
        var products = [];
        var fetchAllCompleted = false;
    
        function getProducts() {
            var deferred = $q.defer();
    
            if (fetchAllCompleted) {
                deferred.resolve(products);
            } else {
                client.product.fetchAll().then((products_complete) => {
                    //do things and get the products ready
                    products.push(item);
                    fetchAllCompleted = true;
                    deferred.resolve(products);
                });
            }
    
            return deferred.promise;
        }
    
    
        return {
            getProducts: getProducts
        }
    });
    

    Then in the controller

    serviceApp.controller('CartController', ['shopService', function CartController(shopService) {
        //create a reference to the service variable
        shopService.getProducts().then(function(products) {
            this.products = products;
        });
    }]);
    

    That should fix your issues.