0

Currently I have a factory and a controller. The factory updates with items from an endpoint and the number of pages of data. My data array is being recognized fine, but my pageCount (int) update never actually changes. I have checked to make sure it isn't actually returning 0.

.factory('myService', function($http) {
    return {
        data: [],
        update: update,
        pageCount: 0
    };

    function update() {
        return $http.get('path/to/endpoint')
            .then(function(res) {
                angular.copy(res.data.itemsArray, this.data);
                angular.copy(res.data.pageCount, this.pageCount);
                // also tried this.pageCount = res.data.pageCount;
            }.bind(this));
    }
})

.controller('myCtrl', function(myService) {
    myService.update();

    $scope.data = myService.data;
    $scope.pageCount = myService.pageCount;
});

<div>{{pageCount}}</div> // This does not update at all
<div ng-repeat="item in data">{{item}}</div>  // This works fine
diplosaurus
  • 2,538
  • 5
  • 25
  • 53

2 Answers2

1

You are returning a promise with the update() function so you can use then to handle the result (this will give a more consistent result):

.factory('myService', function($http) {

    return {
        update: update
    };

    function update() {
        return $http.get('path/to/endpoint')
            .then(function(res) {
                var result = {
                    data: [],
                    update: update,
                    pageCount: 0
                };

                result.data = res.data.itemsArray;
                result.pageCount = res.data.pageCount;
                return result;
            });
    }
})

.controller('myCtrl', function(myService) {

    $scope.data = [];  

    myService.update().then(function(result) {

        $scope.data = result.data;
        $scope.pageCount = result.pageCount;
    });
});
Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
  • Not to be pedantic but just so I understand correctly, should `var obj` be `var result`? – diplosaurus Jan 28 '15 at 19:09
  • yes. edited. Thanks, I was half way through writing this answer this morning when the question was closed. Had to save it in a text file until now. :) – Davin Tryon Jan 28 '15 at 19:10
  • I tried this out and got a `Provider 'myService' must return a value from $get factory method`. Presumably because factory needs to provide a return value. I tried both changing to a service and setting `this.update` equal to the function and also leaving it a factory and just returning an object with `update: function() {...}` - both of these things caused the browser to hang indefinitely. I'm wondering if the reference to `update` inside itself is causing an issue. – diplosaurus Jan 28 '15 at 20:33
  • @diplosaurus Yes, you must return an object from a factory. I've made the edit to add back in expose the `update` method. – Davin Tryon Jan 28 '15 at 22:29
0

When you assign the primitive from the service, the reference was lost. Try fetching pageCount from a getter in the service instead. Trying to override the service value is a totally different value to the one in the scope.

It doesn't happen to the array because it's a reference and you used copy.

factory('myService', function($http) {
    var pc = 0;
    return {
        data: [],
        update: update,
        pageCount: function() {
            return pc;
        }
    };

    function update() {
        return $http.get('path/to/endpoint')
            .then(function(res) {
                angular.copy(res.data.itemsArray, this.data);
                pc = res.data.pageCount;
            }.bind(this));
    }
})

.controller('myCtrl', 

    function(myService) {
        myService.update();

        $scope.data = myService.data;
        $scope.pageCount = myService.pageCount;
    });

    <div>{{pageCount()}}</div> // This does not update at all
    <div ng-repeat="item in data">{{item}}</div>  // This works fine
Peter Ashwell
  • 4,292
  • 2
  • 18
  • 22