javascript - Making AngularJS ui-router / app wait for $http data to prevent FOUC -


i have following question... or situation. have states defined in angularjs app, so...

$stateprovider             .state('myapp', {                 abstract: true,                 template: '<ui-view/>'             })             .state('myapp.stateone', {                 url: 'state1',                 templateurl: '/an/views/state-1.html',                 controller: 'stateonectrl'             })             .state('myapp.statetwo', {                 url: 'state2',                 templateurl: '/an/views/state-2.html'                 controller: 'statetwoctrl'             })             .state('myapp.statethree', {                 url: 'state3',                 templateurl: '/an/views/state-3.html'                 controller: 'statethreectrl'             }) 

there more states , have changed naming example, suppose need check if user allowed see / load 'mayapp.statethree'. can determine asking backend. have service (in example called isallowedservice) deal requests / provide access , write logic check in .run() block in app.js file example:

.run(['isallowedservice', '$state', function (isallowedservice, $state) {          $rootscope.$on('$statechangesuccess', function (event, tostate, toparams, fromstate) {              // check if going sfm.addcontacts , if allowed to...             if (tostate.name === 'myapp.statethree') {                 isallowedservice.checkifisallowed().then(function (resp) {                     if(resp.allowed === false) {                         $state.go('myapp.stateone');                     }                 });             }          });  }]); 

this works doesn't wait until result service 'mayapp.statethree' loaded redirected if necessary. quick flash of page before redirected. put same code 'statethreectrl' still flash / fouc. possible resolve when defining states, know won't work this...

.state('myapp.statethree', {     url: '/an/state3',     templateurl: '/an/views/state-3.html'     controller: 'statethreectrl',     resolve: {         isallowed : function () {         isallowedservice.checkifisallowed().then(function (resp) {             return resp;             })         }     } 

i realise wouldn't able inject service (or $http service) possible me somehow pause loading of view / controller of 'mayapp.statethree' until result isallowedservice.checkifisallowed(). advice on how structure app / code appreciated. have used ng-cloak in html view did nothing!

actually you're doing right in application's run block. except not preventing anything. can achieve adding:

  event.preventdefault(); //prevent going page 

furthermore, can add custom data $states , allow verify conditions criteria. e.g.:

$stateprovider.state('home', {   controller: 'homecontroller home',      url: '/home',   templateurl: 'home.html',   data: { roles: [roles.anonymous] }}); //this can condition  $stateprovider.state('user', {   controller: 'usercontroller user',    url: '/user',   templateurl: 'user.html',    data: { roles: [roles.admin, roles.user] }}); 

you can retrieve custom data in $statechangestart event:

  $rootscope.$on('$statechangestart', function (event, next) {     if (!yourservice.isauthorized(next.data.roles)) {        event.preventdefault(); //prevent going page -> no flickering       $state.go('403'); //or whatever desired.     }    }); 

you see flickering because you're using promise , first page gets redirected when promise furfilled. can stop flickering preventing default action, authorize , continue flow desire when promise resolves.

       if (tostate.name === 'myapp.statethree') {             event.preventdefault(); //preventing request.             isallowedservice.checkifisallowed().then(function (resp) {                 if(resp.allowed === false) {                     $state.go('myapp.stateone');                 } else { //he allowed go state three.                    $state.go('myapp.statethree');                 }              }, function() { //in case server has no answer               $state.go('myapp.stateone'); //you want prevent         } ); 

in opinion, if these conditions not change during runtime, i.e. user role based, can retrieve them upon user verification don't need promise begin with. hope helps.

i made similar post before , added working plunker.


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

android - CollapsingToolbarLayout: position the ExpandedText programmatically -

Listeners to visualise results of load test in JMeter -