0

There is a way to delay changing routes until the model is loaded using a resolve object.

See here for details:

Delay changing routes until model loaded

Is it possible do something similar for controllers (not using routes)? I would like to avoid the flicker associated with rendering a model that is retrieved asynchronously.

Something like:

var resolve = { 
                  data1: function($http) { 
                      return  $http({ url:'/someurl1', method: 'GET'});
                  },
                  data2: function($http) {
                      return $http({url: '/someurl2', method: 'GET'});
                  }
               };

 // I know this doesn't exist, but you get the idea about what I'm trying to do.
 app.resolvers(resolve);

 // Then inject data1 and data2 into the controller.  
 // The controller should not load until data1 and data 2 have been resolved.
 app.controller('myController', function($scope, data1, data2) { ... });
Community
  • 1
  • 1
Michael Kang
  • 52,003
  • 16
  • 103
  • 135
  • May I ask why you want to do this?. That way I could give you a better answer. usually you work with promises all the way into the controllers. – Leon Radley Jun 13 '14 at 07:04
  • Avoid flicker, the same reason that it exists for delaying changing routes using the resolve object. – Michael Kang Jun 13 '14 at 07:06
  • I would simply display a load indicator as long as the data is undefined and have a ng-show="mydata.length > 0". That way the user gets a ui change straight away. I used resolves a lot in the beginning to load data, but clicking on a navigation button and nothing happens, that's not good UI design. – Leon Radley Jun 13 '14 at 07:11
  • Thanks, but I'm not looking for a work-around. I have a feeling that Angular does not support this, unless someone can show otherwise? A resolvers() function would be a great addition to Angular. – Michael Kang Jun 13 '14 at 07:28
  • How do you instanciate the controller? ng-controller="mycontroller"? – Leon Radley Jun 13 '14 at 12:36
  • Yes, the typical way, by adding ng-controller attribute to an element. – Michael Kang Jun 13 '14 at 12:51
  • The answer to this would involve a way to complete an asynchronous $http call, have the result as an injectable, and then resolve the promise *before* the controller function is called. – Michael Kang Jun 13 '14 at 12:58
  • You could propably do it if you wanted, by creating a custom directive which has a higher priority than ng-controller. then say it's terminal: true to make angular not run the ng-controller, and then in the custom directive use the $controller to instansiate the ng-controller when you are done resolving your promises. But you would still need to define the resolve properties on a attribute, and you would need a controller for that, so it would get messy. – Leon Radley Jun 13 '14 at 13:10
  • Not ideal, I could see how that might work. Thinking about it, perhaps the only clean way would be write a factory and manually invoke XMLHttpRequest to run synchronously: var xhr = new XMLHttpRequest(); xhr.open("GET", "/bar/foo.txt", false); – Michael Kang Jun 13 '14 at 13:28
  • have a look at https://github.com/ajoslin/angular-promise-tracker it allows you to add a tracker to $http calls which allows you to nicely implement a spinner for different api calls. works like a charm :) – Leon Radley Jun 13 '14 at 13:32

1 Answers1

-1

If you are using the angular-ui-router so you have that feature built-in. For Example:

myApp.config(function($stateProvider)
{
    $stateProvider
         .state('myState', {
               url: '/',
               controller: 'MyController',
               resolve: {
                    myData: function(MyService)
                    {
                         return MyService.loadAsyncData();
                    }
               }
          }
    }

You can read more about it here: https://github.com/angular-ui/ui-router/wiki

Dotan Simha
  • 742
  • 1
  • 5
  • 12
  • Take a look at this: [$routerProvider docs](https://docs.angularjs.org/api/ngRoute/provider/$routeProvider), There is a section that explains the resolve in ngRoute. Anyway, I highly recomment to use Angular UI Router for working with routes, it has a lot of powerful features that ngRoute does not have. – Dotan Simha Jun 14 '14 at 10:02