0

I would like to delay the initialization of the AppCtrl and any route change until the "app settings" have arrived from the server.

I'm using the AngularJS-boilerplate which is including ui-route and ui-state. None of the solutions i found so far did actually defer the AppCtrl launch and the routing.

All the console.log fire right at launch, except for the "at resolve".

Javascript app.js

 var app = angular.module( 'ngBoilerplate', [
  'templates-app',
  'templates-common',
  'ngBoilerplate.foo',
  'ui.state',
  'ui.route'
]);


app.config( function myAppConfig ( $stateProvider, $urlRouterProvider, $translateProvider ) {
    console.log('greetings from config');
    // Routes
    $stateProvider.state('home', {
        controller:"AppCtrl",
        resolve:{
            app: function ($q, $timeout) {
                var defer = $q.defer();
                console.log('before resolve');
                $timeout(function () {
                    console.log('at resolve');
                    defer.resolve();
                }, 2000);
                return defer.promise;
            }
        }
    });

    $urlRouterProvider.when('/foo','/foo/tile');
    $urlRouterProvider.otherwise( '/foo' );
});

app.run(function run( $rootScope, $state, $stateParams, titleService, dataFactory ) {
    console.log('greetings from run');
    $state.transitionTo('home');
});

var AppCtrl = app.controller( 'AppCtrl', function AppCtrl ( $scope, $location ) {
    console.log('greetings from AppCtrl');
});

Javascript foo.js

angular.module( 'ngBoilerplate.foo', [
  'ui.state',
  'placeholders',
  'ui.bootstrap'
])

.config(function config( $stateProvider ) {
  $stateProvider
      .state( 'foo', {
        url: '/foo/:type',
       views: {
            "navigation": {
                templateUrl: "navigation/navigation.tpl.html"
            },
            "footer": {
                templateUrl: "navigation/footer.tpl.html"
            },
            "main": {
                controller:'FooCtrl',
                templateUrl: function(stateParams) {
                    if(stateParams.type == null) {
                        stateParams.type = 'tile';
                    }
                    return "foo/foo."+(stateParams.type == null || stateParams.type == 'tile' ? 'tile' : 'list')+".tpl.html";
                }
            }
        }
      })
.controller( 'FooCtrl', function FooCtrl( $scope ) {
  console.log('deferred FooCtrl');
});
Kilian Schefer
  • 579
  • 5
  • 18
  • Hi, I Suggest you to add a factory service and use that in resolve for your reference check this post http://stackoverflow.com/questions/18010796/return-interdependent-async-promises-in-routeprovider-resolve – JQuery Guru Aug 15 '13 at 07:42
  • Just tried that out. I now have a factory that behaves exactly like my code above. AppCtrl is being started _before_ the promise was resolved. – Kilian Schefer Aug 15 '13 at 12:02
  • OK, i didn't have to add
    which obviously bypassed the resolve and launched the AppCtrl right away. I'm still interested in how i can defer any state change till the app settings are being loaded.
    – Kilian Schefer Aug 15 '13 at 15:29
  • Several Ideas: 1) Controllers in states won't be instantiated without a template to pair it to. So maybe the fact the the controller is running at all is a bug and it runs right away because there is no template defined. 2) Use onEnter instead of a controller and a resolve. 3) Have a state called loading and when you resolve your stuff in the onEnter or controller (whatever you decide) then use $state.transitionTo("homestate") or whatever. – Tim Kindberg Aug 16 '13 at 01:08

0 Answers0