Search code examples
javascriptangularjsindexeddbangular-controller

How to load data which is used by the entire AngularJs Application?


In my application there is some data which is used by other controllers to do their job.

So for example I need the user and some other entities to do REST calls to the server.

At the moment I have an AppController (app.js) which loads basic data which will be used by controllers of all ng-views (see index.html). The functions loadUser() and loadRequiredEntity() store values received from REST-Calls in indexedDb.

Any controller of ng-views which are displayed (see ng-view in index.html) read the loaded data from indexedDb.

I think there are some mayor problems with this approach:

  • Does AppController load all Data before controllers of ng-view try to access them?
  • loadUser() and loadRequiredEntity() call services (for example userService) which execute rest-calls and return promises so AppController is finished before the entire data was loaded, right? So the controllers of ng-views begin to read from indexedDb before any value is stored there.

How do I load basic data which is required to be there for use by other controllers? Is an AngularJs controller the right choice?

index.html:

<body ng-app="app" id="appBody" ng-controller="AppController as appCtrl">
    <md-content id="content" ng-view=""></md-content>
</body>

app.ts:

/// <reference path="../typings/tsd.d.ts" />
module app {
      export class AppController {

          static $inject = ['$log'];

          private _LOG_PREFIX : string = 'AppController: ';

          constructor(private $log: ng.ILogService) {
          this.$log.info(this._LOG_PREFIX + 'started');
          this.loadUser()
          .then(this.loadRequiredEntity)
          .then(this.markAsAuthenticated, this.handleLoadBasedataError);
          }
          ...
      }
}

Solution

  • As Melou mentioned ui-router solves the problem.

    The basic data is loaded in an abstract state.

    module app.core {
        "use strict";
        import LoadBasicDataService = app.core.services.LoadBasicDataService;
    
        function loadBasicDataForControllers(loadBasicDataService: LoadBasicDataService) : ng.IPromise<any> {
            return loadBasicDataService.load();
        }
        loadBasicDataForControllers.$inject = ['loadBasicDataService'];
    
        function configureCore($urlRouterProvider: angular.ui.IUrlRouterProvider, $stateProvider: angular.ui.IStateProvider){
    
        $urlRouterProvider.otherwise("/myComponent1");        
    
        $stateProvider
            .state("main",{
               templateUrl: "layout/main.html",
               abstract: true,
               resolve: {
                   'loadBasicDataForController': loadBasicDataForControllers
               }
            })
            .state("main.myComponent2",{
               url: "/myComponent2",
               template: "<myComponent2></myComponent2>"
            })
            .state("main.myComponent1",{
               url: "/myComponent1",
               template: "<myComponent1></myComponent1>"
            });
        }
        configureCore.$inject = ["$urlRouterProvider", "$stateProvider"];
    
        angular
        .module("app.core")
        .config(configureCore);
    }