Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preload JSON data so its available when Angularjs module is ready

Tags:

json

angularjs

I have a very simple app that loads a JSON array using $http.get inside of a controller. It assigns the result data to scope and the HTML repeats through the results to display a list. It is a very simple angularjs example.

function ViewListCtrl($scope, $http) {

$scope.shoppinglist = [];

$scope.loadList = function () {

    var httpRequest = $http({
        method: 'POST',
        url: 'viewList_service.asp',
        data: ''

    }).success(function (data, status) {
        $scope.shoppinglist = data;
    });

};

$scope.loadList();

}

While testing on a slow server I realized there was a 3 second blocking delay while rending the repeat region. Debugging revealed to me that my controller does not attempt to get the data until the page is loaded. My page takes 3 seconds to load. Then I must wait another 3 seconds for the json data to load.

I want to load data as soon as possible so it is ready when my controller is ready. Simply put, I want to pre-load the data so it loads in parallel to my module.

I've searched all over and the closest thing I found was "resolve", but I am not using routes. This is a very simple list and no routes or templates.

How can I load the JSON as soon as the page starts to render so it is ready when the controller is ready and there is no blocking... and then get that data into scope?

like image 259
user2341148 Avatar asked Dec 20 '13 07:12

user2341148


2 Answers

You can use the module.run method. Which is executed after the config stage is completed. To make use of this you need to create a service factory that does the actual query and caches the result

module("myapp",[]).factory('listService', function($q,$http) {
    var listData;
    var defer = $q.defer();
    return  {
       loadList: function() {
          if(listData) {
               defer.resolve(listData);
          }
          else {

              var httpRequest = $http({
                 method: 'POST',
                 url: 'viewList_service.asp',
                 data: ''
             })
             .success(function(data) { 
                 listData=data;
                 defer.resolve(listData);
             }
        }
        return defer.promise;
   }
}
});

In your controller you still use the factory to get the data with a promise then wrapper.

listService.loadList().then(function(data) {
   $scope.shoppinglist=data;

});

This way you can make the async call even before any controller related code executes.

like image 140
Chandermani Avatar answered Oct 14 '22 04:10

Chandermani


You can load data by writing code (something like Chandermani's listService) in separate file but without using angular. you can use jquery ajax to load your data.

Then write a service in angular to read that data and pass it to your controller.

like image 21
Alborz Avatar answered Oct 14 '22 03:10

Alborz