AngularJS 1.2 storage of data arrays in services

I have a question how to get information on how to get data stored in service arrays to the controller, since the deployment of promises was removed in 1.2.

Example:

  • Route One contains a list of items
  • Route two contains a form for adding a new item
  • Once the item has been saved from the route tug, the user is redirected back to the first route.

When the first route is initially loaded, the service will make a request to the server for the elements, store the elements in an array in the service, so that each request for the route alone after that simply returns an array. When an item was saved, that item was moved to an array in the service.

If I expected a promise in the first controller on boot, there is no problem because the response was sent back, but each routing request alone would return an error after that, because I was returning an array.

Any ideas on how to accomplish something like this in 1.2?

app.factory('Items',function($http) {
    var items = [];
    return {
        list: function() {
            if (items.length == 0) {    // items array is empty so populate it and return list from server to controller
                return $http.get('/?items').then(function(response) {
                    items = response.data.items;
                    return response.data.items;
                });
            }
            return items;   // items exist already so just return the array
        },
        save: function(item) {
            return $http.post('/',{item:item}).then(function(response) {
                items.push(item);
                return response;
            });
        }
    }
});

app.controller('RouteOne',function($scope,Items) {
    Items.list().then(function(response) {
        $scope.items = response;
    });

    /* used to be this before unwrapped promises were removed
    $scope.items = Items.list();
    */

});

app.controller('RouteTwo',function($scope,Items) {
    $scope.new_item = {};
    $scope.addItem = function() {
        Items.save($scope.new_item).then(function(response) {
            $location.path('/');    // back to route one
        });  
    };
});
+3
source share
2 answers

You can return the service to your own promises, which can resolve either with a cached value or with the result of the $ http promise. I have not fully tested this, but it might look something like this:

app.factory('Items', function($q, $http) {
    var items = [];
    return {
        list: function() {
            var deferred = $q.defer();
            if (items.length == 0) {    // items array is empty so populate it and return list from server to controller
                $http.get('/?items').then(function(response) {
                    items = response.data.items;
                    deferred.resolve(response.data.items);
                });
            } else {
                deferred.resolve(items);   // items exist already so just return the array
            }
            return deferred.promise;
        },
        save: function(item) {
            return $http.post('/',{item:item}).then(function(response) {
                items.push(item);
                return response;
            });
        }
    }
});

app.controller('RouteOne',function($scope,Items) {
    Items.list().then(function(response) {
        $scope.items = response;
    });

});

, , , , , , .

+5

, , - XHR

- js .

Items.save items


jsfiddle

var app = angular.module('app', ['ui.router']);

app.config(function ($stateProvider) {
    $stateProvider
        .state('one', {
            url: '/',
            template: '<ul><li data-ng-repeat="item in items">{{item.value}}</li></ul><a href=#/two>Route two</a>',
            controller: 'RouteOne'
        })
        .state('two', {
            url: '/two',
            template: '<input data-ng-model="new_item.value"></input><button data-ng-click="addItem()">Add item</button>',
            controller: 'RouteTwo'
        });
});

app.run(function ($state) {
    $state.go('one');
});

app.factory('Items',function($http) {
    var items = [];
    return {
        list: function() {
            if (items.length === 0) {    // items array is empty so populate it and return list from server to controller
                // i just modified a little the request for jsfiddle
                $http.get('/echo/jsonp/?items=[{"value": 1},{"value": 2},{"value": 3},{"value": 4},{"value": 5}]').then(function(response) {

                    // you won't need next line  with a real server
                    response.data = JSON.parse(response.data.items);
                    Array.prototype.push.apply(items, response.data);
                });

                // simply always return the reference to items
                // as it will be populated later
                return items;
            }
            return items;   // items exist already so just return the array
        },
        save: function(item) {
            return $http.post('/echo/jsonp/',{item:item}).then(function(response) {
                items.push(item);
                return response;
            });
        }
    }
});

app.controller('RouteOne',function($scope,Items) {
    // don't do anything as you the binding does the work for you
    $scope.items = Items.list();
});

app.controller('RouteTwo',function($scope,Items, $location) {
    $scope.new_item = {};
    $scope.addItem = function() {
        Items.save($scope.new_item).then(function(response) {
            $location.path('/');    // back to route one
        });  
    };
});
+2

All Articles