2012-08-14 25 views
44

Tengo una aplicación creada usando AngularJS y un servidor del lado del servidor que entrega todas las solicitudes en formato JSON. Todas y cada una de las solicitudes se envuelven en un contenedor JSON que contiene una variable de datos que contiene los datos específicos de la solicitud. Los demás datos, que se utilizan para mantener el estado y el control dentro de la aplicación, verifican los errores y los mensajes de éxito, y verifican los indicadores de sesión. Todas estas otras variables se sirven con CADA solicitud y se examinan primero antes de que la variable de datos sea.

Ahora tengo un método para examinar el contenido de la respuesta JSON primero y luego los datos en sí.

$http.get('something.json').success(function(response) { 
    var data = examineJSONResponse(response); 
    //do the data stuff 
}); 

Esto funciona y el examineJSONResponse toma un vistazo al código y si hay algo mal, entonces se produce una excepción y vuelve a cargar la página utilizando window.location.href.

¿Hay alguna forma de que pueda automatizar esto dentro de AngularJS de modo que cada vez que se realiza una llamada $ http, compruebe esto y SÓLO devuelva los datos de la variable de datos como la respuesta JSON?

Respuesta

85

Puede interceptar respuestas agregando un interceptor a $httpProvider.interceptors con Angular 1.1.4+ (consulte la documentación here búsqueda de interceptores).

Para un tipo de contenido específico como json, puede potencialmente rechazar cambios o lanzar una excepción incluso si la llamada fue un éxito. Puede modificar el response.data que se van pasando a su código del controlador, así aquí:

myModule.factory('myHttpInterceptor', function ($q) { 
    return { 
     response: function (response) { 
      // do something on success 
      if(response.headers()['content-type'] === "application/json; charset=utf-8"){ 
       // Validate response, if not ok reject 
       var data = examineJSONResponse(response); // assumes this function is available 

       if(!data) 
        return $q.reject(response); 
      } 
      return response; 
     }, 
     responseError: function (response) { 
      // do something on error 
      return $q.reject(response); 
     } 
    }; 
}); 
myModule.config(function ($httpProvider) { 
    $httpProvider.interceptors.push('myHttpInterceptor'); 
}); 

NOTA: Aquí está la respuesta original para las versiones anteriores a 1.1.4 (responseInterceptors quedaron en desuso con el angular 1.1 0.4):

Tal vez hay una manera mejor, pero creo que se puede hacer algo similar a this post con el interceptor de respuesta HTTP (descrito here) (para un tipo de contenido específico, como JSON) donde potencialmente rechazar los cambios o º remar una excepción a pesar de que la llamada fue un éxito. Puede modificar el response.data que pasará a su código de controlador también aquí.

myModule.factory('myHttpInterceptor', function ($q) { 
    return function (promise) { 
     return promise.then(function (response) { 
      // do something on success 
      if(response.headers()['content-type'] === "application/json; charset=utf-8"){ 
       // Validate response if not ok reject 
       var data = examineJSONResponse(response); // assumes this function is available 

       if(!data) 
        return $q.reject(response); 
      } 
      return response; 
     }, function (response) { 
      // do something on error 
      return $q.reject(response); 
     }); 
    }; 
}); 
myModule.config(function ($httpProvider) { 
    $httpProvider.responseInterceptors.push('myHttpInterceptor'); 
}); 
+0

funciona como un encanto. – matsko

+0

¿Cómo registro este interceptor con angular? –

+1

@MikeyCee Modifiqué el ejemplo para incluir el registro del interceptor. ¡Espero que esto ayude! – Gloopy

7

Otra solución es crear un servicio y usarlo alrededor de la variable $ http.

angular.module('App', []) 
    .factory('myHttp',['$http',function($http) { 
    return function(url, success, failure) { 
     $http.get(url).success(function(json) { 
      var data = examineJSONResponse(json); 
      data && data.success ? success() : failure(); 
     }).error(failure); 
    ); 
    } 
}]); 

Y ahora esto puede ser llamado como:

myHttp(url, onSuccess, onFailure); 
+2

Su código no se ejecuta porque el segundo parámetro del método 'service' debe ser una función constructora, como se explica en [este hilo en la lista de correo de AngularJS] (https://groups.google.com/forum/# ! msg/angular/56sdORWEoqg/b8hdPskxZXsJ). Creo que probablemente quisiste escribir 'factory' en lugar de' service' y eso funcionaría. – tamakisquare

+0

Tienes razón. Debería ser una 'fábrica'. Ahora está actualizado. Gracias. – matsko

Cuestiones relacionadas