redconservatory
redconservatory

Reputation: 21934

Angular ui-router: Is there a way to set a template load timeout?

Is there a way to set a default "time out" for a template load?

My template says "pending" (Chrome > Network Tab) even after a minute. It's an intermittent problem...just every once in a while a template will take an indefinite amount of time to load.

What I would like is to be able to handle the error instead of waiting indefinitely for my page to load.

Upvotes: 1

Views: 581

Answers (1)

New Dev
New Dev

Reputation: 49590

There isn't an obvious way to do this. When you supply templateUrl, the $http request that is made does no have a timeout property. To be able to cancel, you'd need to make your own $http call.

This is possible with a templateProvider property. You can wrap this functionality in a service to make it less cluttered:

.factory("viewTemplateSvc", function($http, $templateCache){
  return {
    get: function(url, timeout){
      return $http
        .get(url, { 
              cache: $templateCache, 
              headers: { Accept: 'text/html' },
              timeout: timeout // timeout in milliseconds
            })
        .then(function(response) { 
          return response.data; 
        });                  {
    }
  }
})
.config(function($stateProvider){
  $stateProvider
     .state("stateA",
              {
                templateProvider: function(viewTemplateSvc){
                  return viewTemplateSvc.get("views/stateA.html", 2000);
                },
                // etc...
              });

})

This is, of course, rather messy and not very DRY. You can, of course, rely on some default timeout, but you need to specify the templateProvider for every state.

One way to avoid this, is to use $stateProvider.decorator and substitute every occurance of templateUrl with templateProvider:

$stateProvider.decorator("views", function(state, viewsFn){
  var views = viewsFn(state);
  angular.forEach(views, function(config, name){
    if (config.templateUrl){
      var url = config.templateUrl;
      config.templateUrl = undefined;

      config.templateProvider = function(viewTemplateSvc){
         return viewTemplateSvc.get(url, 2000);
      }
    }
  });
  return views;
});

Then, you could just continue using templateUrl as before.

Upvotes: 3

Related Questions