Smart Tech for a better Web

Intercept Ajax requests with Angular.js

von

Angular.js is a great framework for developing JavaScript applications. I have recently started to migrate one of my applications to it and I am impressed how much of my code can simply go to trash. One of my current use cases is to unwrap JSON. All the JSON which comes from my server is commented with /**/ to avoid a security problem. Now I want to do the same with Angular.js: make some magic, which unwraps all of my AJAX requests automatically. After I understood how to do it, it is actually very easy.

Create your own Interceptor.

This is similar to create an Angular.js service. First, we need to create our application module and depend our bootstrapping to the $provide and $httpProvider services.

angular.module('myapp', [], function($provide, $httpProvider) {
   // our initialization code follows here
})

With that we can create our interceptor, which is basically created like a Angular.js service.

angular.module('myapp', [], function($provide, $httpProvider) {
   $provide.factory('myHttpInterceptor', function($q) {
        return function(promise) {
            // intercepting
        }
   }
})

$provide is a service which adds the "myHttpInterceptor" factory to the Dependency Injection Manager. The $http service will need to look it up later. Of course this is no black magic, we need to add our interceptor to the list of response interceptors with the following line, right after we created the interceptor service:

$httpProvider.responseInterceptors.push('myHttpInterceptor');

The interceptor implementation

After that, we can already start with the implementation of the interception method itself

return promise.then(
   function(response) {
      response.data = safeJson(response.data);
      return response;
   }, function(response) {
      response.data = safeJson(response.data);
      return $q.reject(safeJson(response.data));
   });
}

Here we created two callbacks, one for success and the second one for failure. Both handlers call the safeJson method with response.data, which is holding the actual data from the server. The second one does a reject of further interception. In my specific case, the data block does hold the reasons for rejection.

As I will not outline the concept of promises in this blog post, you might want to take a look at the great promise docs from Angular.js.

Fur convenience, here is the full code, including the safeJson method which reduces /**/ from my server string.

angular.module('myapp', [], function($provide, $httpProvider) {
   $provide.factory('myHttpInterceptor', function($q) {
      return function(promise) {
         // Safe JSON
         var safeJson = function (textValue) {
            var unwrapped = textValue.substring(2).substring(0, temp.length - 2);
            unwrapped = $.trim(unwrapped);
            if (unwrapped.length === 0) {
              return null;
            } else {
              return JSON.parse(unwrapped);
            }
         };

       return promise.then(
          function(response) {
             response.data = safeJson(response.data);
             return response;
          }, function(response) {
             response.data = safeJson(response.data);
             return $q.reject(safeJson(response.data));
          });
       }
   });
   $httpProvider.responseInterceptors.push('myHttpInterceptor');
})

Final note on the build in security mechanism

As a last word, I have had a custom way how I deal with the JSON problem. If you don't have a custom problem and can freely choose, you might want to look at the build in mechanics which solves exactly my problem, just without additional code.

Tags: #AngularJS #JavaScript

Newsletter

ABMELDEN

BLOG-POST TEILEN

When you load these comments, you'll be connected to Disqus. Privacy Statement.