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
4
  • @BenjaminGruenbaum, I don't think this a duplicate. The OP is binding this with bind(this). Commented Jan 28, 2015 at 8:07
  • @BenjaminGruenbaum could you add why it's a duplicate? My this assignments are working correctly for the array, but not for the primitive. I didn't see anything in your linked answer about that change. Commented Jan 28, 2015 at 8:10
  • 3
    @diplosaurus sorry, I missed the bind, reopened. Commented Jan 28, 2015 at 8:19
  • @diplosaurus can you create a short fiddle (or plnkr) illustrating the issue? Commented Jan 28, 2015 at 11:17

2 Answers 2

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;
    });
});
Sign up to request clarification or add additional context in comments.

4 Comments

Not to be pedantic but just so I understand correctly, should var obj be var result?
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. :)
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 Yes, you must return an object from a factory. I've made the edit to add back in expose the update method.
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

3 Comments

below the angular.copy in a comment I also tried that assignment with no luck.
Hey, sorry figured it out. Try my last edit. Be careful using primitives in services
Surprisingly didn't work... I tried putting it in a basic object structure and copying like the array. Seems odd that that wouldn't work either.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.