3

This subject has been already asked but I couldn't figure out what to do in my case.

Using AngularJS 1.0.5:

Before showing the view "login", I want to get some data and delay the view rendering while the data isn't loaded from an AJAX request.

Here is the main code. Is it the good way?

angular.module('tfc', ['tfc.config', 'tfc.services', 'tfc.controllers']).config([
 '$routeProvider', '$locationProvider', '$httpProvider',
 function($routeProvider, $locationProvider, $httpProvider) {
  $routeProvider.when('/login', {
    templateUrl: 'views/login.html',
    controller: "RouteController",
    resolve: {
      data: function(DataResolver) {
        return DataResolver();
      }
    }
  });
}
]);

module_services = angular.module("tfc.services", []);

module_services.factory("DataResolver", [
 "$route", function($route) {
  console.log("init");
  return function() {
    // Tabletop is a lib to get data from google spreadsheets
    // basically this is an ajax request
    return Tabletop.init({
      key: "xxxxx",
      callback: function(data, tabletop) {
        console.log("[Debug][DataResolver] Data received!");
        return data;
      }
    });
  };
 }
]);
Laurent
  • 977
  • 3
  • 13
  • 27
  • 2
    Maybe answer from AngularJS' creator can helps you: http://stackoverflow.com/a/11972028/449162 – L42y Mar 06 '13 at 13:22
  • You could also assign the result of the AJAX request to something in your $scope and just use ng-show in the HTML. – boxed Mar 06 '13 at 16:00
  • 1
    This is a pretty solid way to do it. it's way better than using ng-show or ng-hide because in your controller, you'll have your data already and can write more synchronous code. That said, this more suits for a code-review site than SO, because you don't have a problem but looking for improvements in your code. – Umur Kontacı Jul 31 '14 at 23:58
  • @L42y Funny that Misko also asked that question. – Shomz Aug 01 '14 at 00:02
  • possible duplicate of [Delaying AngularJS route change until model loaded to prevent flicker](http://stackoverflow.com/questions/11972026/delaying-angularjs-route-change-until-model-loaded-to-prevent-flicker) – ivarni Aug 04 '14 at 10:48

2 Answers2

1

The point of AngularJS is that you can load up the templates and everything and then wait for the data to load, it's meant to be asynchronous.

Your view should be using ng-hide, ng-show to check the scope of the controller so that when the data in the scope is updated, the view will display. You can also display a spinner so that the user doesn't feel like the website has crashed.

  • I see your point when you load the data to show on a view, but you may need to cancel a route based on async load – Bruno Peres Jul 14 '15 at 18:31
1

Answering the question, the way you are loading data explicitly before the view is rendered seems right. Remember that it may not give the best experience as there will be some time to resolve that, maybe giving an impression that your app stopped for some moments.

See an example from John Pappa's blog to load some data before the route is resolved using angular's default router:

// route-config.js
angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'Avengers',
            controllerAs: 'vm',
            resolve: {
                moviesPrepService: function(movieService) {
                    return movieService.getMovies();
                }
            }
        });
}

// avengers.js
angular
    .module('app')
    .controller('Avengers', Avengers);

Avengers.$inject = ['moviesPrepService'];
function Avengers(moviesPrepService) {
    var vm = this;
    vm.movies = moviesPrepService.movies;
}

You basically use the resolve parameters on the route, so that routeProvider waits for all promises to be resolved before instantiating the controller. See the docs for extra info.

Bruno Peres
  • 2,980
  • 1
  • 21
  • 19
  • When using UI Router, take a look at the docs for `resolve` attribute when declaring a state: http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider#methods_state – Bruno Peres Jul 14 '15 at 19:42