user92083452
user92083452

Reputation: 59

Angular provider (service) for store data fetched from an api rest?

I'm using a controller to load product data into an $rootScope array. I'm using $http service and works fine, but now I have a new function which fetch the number of products to be loaded. I can't use the function cause the response is slow. I was wondering if I could use a provider to load the number of products to fetch in the config method before the apps start. And if I could move the $rootScope array to one service. I don't understand Angular docs, they are not really useful even the tutorial at least in providers and services...

app.controller('AppController', [ '$rootScope', '$http', function ( $rootScope,$http) {

$rootScope.empty = 0;
$rootScope.products = [];
$rootScope.lastId = 0;
$rootScope.getLastID = function () {
 $http.get("app_dev.php/api/products?op=getLastId").success(function (data) {
 $rootScope.lastId = data.lastId;
});
};
$rootScope.getProducts = function () {
  if ($rootScope.empty === 0) {
   for (i = 1; i < 100; i++) {
    $http.get("app_dev.php/api/product/" + i).success(function (data) {
     $rootScope.products.push(data);
    });
   }
  }
 $rootScope.empty.productos = 1;
  };
 }

I have done this with factory and service but is not working.

app.factory('lastProduct', ['$http', function lastProductFactory($http) {
this.lastId;
var getLast = function () {
  $http.get("app_dev.php/api/products?op=getLastId").success(function (data)  {
    lastId = data.lastId;
 });

                    return lastId;
                };

                var lastProduct = getLast();

                return lastProduct;
            }]);

        function productList($http, lastProduct) {
            this.empty = 0;
            this.lastId = lastProduct();
            this.products = []

            /*this.getLast = function () {
                lastId = lastProduct();
            };*/
            this.getProducts = function () {
                if (empty === 0) {
                    for (i = 1; i < lastId; i++) {
                        $http.get("app_dev.php/api/product/" + i).success(function (data) {
                            products.push(data);
                        });
                    }
                }
                empty = 1;
                return products;
            };

        }

        app.service('productsList', ['$http', 'lastProduct' , ProductsList]);

Upvotes: 2

Views: 1381

Answers (3)

user92083452
user92083452

Reputation: 59

I done this but not working . rootScope total is undefined when set method is called from some controller. https://i.sstatic.net/nkqz5.jpg But using 10 instead rootscope total https://i.sstatic.net/rXHjb.jpg I could see that the rootScope total var arrive before the others... (app_dev.php/api/productos?op=ultimaIdProductos) vs (app_dev.php/api/producto/x)

           var app = angular.module('webui', [$http, $rootScope]);

            app.run (function ($http, $rootScope){

                $http.get("app_dev.php/api/products?op=getLastId").success(function (data) {
                    $rootScope.total = data.ultima;                    
                });

            });

                function myData($http, $rootScope) {
                    var myArray = [];

                    return {            
                        set: function () {
                            console.log($rootScope.total);
                            for (i = 1; i < $rootScope.total; i++) {
                                $http.get("app_dev.php/api/product/" + i).success(function (data) {
                                    myArray.push(data);
                                })
                            }

                        },
                        get: function () {
                            return myArray;
                        }
                    }
                }

    app.controller('AppController', ['$http', '$rootScope', 'myData', function ($http, $rootScope, myData) {

                $rootScope.productos = [];

                $rootScope.getProductos = function () {

                    console.log($rootScope.total);
                    myData.set();
                    $rootScope.productos = myData.get();


                };

}]);

Upvotes: 0

Danny Blue
Danny Blue

Reputation: 463

Making that many small $http requests does not seem like a good idea. But using a factory to store an array of data to be used across controllers would look something like this. To use a factory you need to return the exposed api. (The this style is used when using a service. I suggest googling the different but I prefer factories). And if you need to alert other controllers that data has changed you can use events.

angular
    .module('myApp')
    .factory('myData', myData);

function myData($http, $rootScope) {
    var myArray = [], lastId;

    return {
        set: function(data) {
            $http
                .get('/path/to/data')
                .then(function(newData) {
                    myArray = newData;

                    $rootScope.$broadcast('GOT_DATA', myArray);
                })
        },
        get: function() {
            return myArray
        },     
        getLast: function() {
             $http
                .get('/path/to/data/last')
                .then(function(last) {
                    lastId = last;

                    $rootScope.$broadcast('GOT_LAST', lastId);
                })
        }
    }
}

And then from any controller you can inject the factory and get and set the data as you see fit.

angular
    .module('myApp')
    .controller('MainCtrl', MainCtrl);

function MainCtrl($scope, myData) {
    $scope.bindableData = myData.get(); // get default data;

    $scope.$on('GOT_DATA', function(event, data) {
       $scope.bindableData = data;
    })
}

I hope this helps. Let me know if you have any questions.

Upvotes: 0

Dayan Moreno Leon
Dayan Moreno Leon

Reputation: 5435

services are not availables during configuration time, only providers hence you can not use $http to get a value inside the configuration block, but you can use the run block,

you can do

angular.module('app',['dependencies']).
 config(function(){
  //configs
 })
 .run(function(service){
   service.gerValue()
})

setting the retrieved value inside a service or inside a value is a good idea to avoid contaminate the root scope, and this way the value gets retrieved before the services are instantiated and you can inject the retrieved value as a dependency

Upvotes: 1

Related Questions