Angular.js: Angular HTTP interceptor executed for embedded ng-templates

Created on 28 Nov 2014  路  6Comments  路  Source: angular/angular.js

Most helpful comment

I believe that not running interceptors for (cached) templates, would be too much of a breaking change (not to mention there are valid cases where you might want to indeed intercept the template requests).

That said, now we are using $templateRequest (which is a wrapper around $http) for all template requests (duh) and since v1.5.0-beta.2 there is $templateRequestProvider.httpOptions(), which can be used to (among other things) set a special flag on your configs. Then you can easily check the flag from your interceptors and skip interception (if you interceptor does not apply to template requests).
This is similar to checking the $templateCache, but avoids the overhead.

E.g.:

// During config phase
.config(function ($templateRequestProvider) {
  $templateRequestProvider.httpOptions({_isTemplate: true};
})

// In the interceptor
.factory('myInterceptor', function () {
  return {
    ...
    request: function (config) {
      if (config._isTemplate) return config;

      /* Do intercept */
    }
  };
})

Demo pen

A viable "built-in" solution (that wouldn't break existing apps), would be to have $templateRequest add a special flag (pretty much as shown in the example above) and (somehow) allow interceptors to specify an ignoreTemplateRequests option. Then $http could check the flag added by $templateRequest and not pass the template request/response/error through interceptors with ignoreTemplateRequest: true.

Considering all the above, I don't think this is a high priority, but if anyone want's to take a shot at a PR, they're more than welcome :smiley:

All 6 comments

My impression is that "fixing" this would be very problematic as:

  • interceptors are applied to all $http requests
  • $templateCache (any $http cache, for that matter) is caching un-intercepted results

What we would have to do is to either move cache on a different level ("above" interceptors) or have some flag to skip interceptors for a given request (brrrr....). On top of this it seems that the current behaviour is what some people expect....

Given all this I don't see this being changed in 1.3.x, unless someone has a smart solution here. Your best option for now is to explicitly ignore templates (based on a path and / or extension) in your interceptor(s)...

Given all this I don't see this being changed in 1.3.x, unless someone has a smart solution here. Your best option for now is to explicitly ignore templates (based on a path and / or extension) in your interceptor(s)...

I think this is the temporary solution for now.

Thanks very much for helping!

Any update on this (or roadmap)?

As a workaround, I'm currently checking the cache before doing anything:

...
.factory('myIntelligentInterceptor', function($log, $templateCache) {
        return {
            request : function(config) {
                config.alreadyCached = $templateCache.get(config.url);
                if (!config.alreadyCached) {
                    // do intercept-things with request
                }
                return config;
            },
            response : function(response) {
                if (!response.config.alreadyCached) {
                    // do intercept-things with response
                }
                return response;
            }
        };
    });
})();

I believe that not running interceptors for (cached) templates, would be too much of a breaking change (not to mention there are valid cases where you might want to indeed intercept the template requests).

That said, now we are using $templateRequest (which is a wrapper around $http) for all template requests (duh) and since v1.5.0-beta.2 there is $templateRequestProvider.httpOptions(), which can be used to (among other things) set a special flag on your configs. Then you can easily check the flag from your interceptors and skip interception (if you interceptor does not apply to template requests).
This is similar to checking the $templateCache, but avoids the overhead.

E.g.:

// During config phase
.config(function ($templateRequestProvider) {
  $templateRequestProvider.httpOptions({_isTemplate: true};
})

// In the interceptor
.factory('myInterceptor', function () {
  return {
    ...
    request: function (config) {
      if (config._isTemplate) return config;

      /* Do intercept */
    }
  };
})

Demo pen

A viable "built-in" solution (that wouldn't break existing apps), would be to have $templateRequest add a special flag (pretty much as shown in the example above) and (somehow) allow interceptors to specify an ignoreTemplateRequests option. Then $http could check the flag added by $templateRequest and not pass the template request/response/error through interceptors with ignoreTemplateRequest: true.

Considering all the above, I don't think this is a high priority, but if anyone want's to take a shot at a PR, they're more than welcome :smiley:

I agree that changing this would be a BC and that there's an adequate workaround

Was this page helpful?
0 / 5 - 0 ratings