À l'aide de ngResource
dans AngularJS 1.2rc (x), comment puis-je obtenir le code de statut maintenant?
RestAPI.save({resource}, {data}, function( response, responseHeaders ) {
});
où RestAPI
est ma ngResource
.
La réponse contient l'objet $promise
et la ressource est renvoyée du serveur, mais n'a plus d'état. La fonction responseHeaders()
a un statut uniquement si le serveur injecte le code de statut dans l'objet d'en-tête, mais pas le code de statut renvoyé. Donc, certains serveurs peuvent le servir et d'autres non.
Vous devez ajouter un intercepteur dans votre déclaration de ressource. Comme ça:
var resource = $resource(url, {}, {
get: {
method: 'GET'
interceptor: {
response: function(response) {
var result = response.resource;
result.$status = response.status;
return result;
}
}
}
});
Usage:
resource.get(params, function(result) {
console.log(result.$status)
});
Le code d'état d'OMI aurait dû être fourni par défaut . Il y a un problème pour ce https://github.com/angular/angular.js/issues/8341
Vous pouvez utiliser les rappels promis then
, catch
et finally
après l'appel $resource
.
Par exemple. Si vous voulez intercepter une erreur après un appel, procédez comme suit:
RestAPI.save({resource}, {data}, callbackFunction).$promise.catch(function(response) {
//this will be fired upon error
if(response.status == 500) alert('Something baaad happend');
}).then(function() {
//this will be fired upon success
});
L'objet response
aura les propriétés status
et statusText
. status
étant un code de statut entier et statusText
le texte. Vous aurez également la propriété data
contenant la réponse du serveur.
edit: comme suggéré, c'était response.status
Pour ceux qui utilisent une version plus récente de Angular, on dirait que nous avons accès au code de statut en tant que troisième paramètre de la fonction transformResponse
/ depuis angular 1.3 , mais cela n'a jamais été correctement documenté dans la ressource $ . docs.
Vous pouvez obtenir le statut de réponse comme ceci:
$http.get(url).then(function(response){
console.log(response.status); //successful status like OK
}, function(response){
console.log(response.status); //error status like 400-Bad Request
})
J'ai convenu que la fonction responseHeaders()
ne renverra que l'en-tête de la réponse, mais vous pouvez le personnaliser et c'est utile quand même.
Pour résoudre votre problème. Avec ce qui suit: ($$service
est mon instance de ressource $.)
var serve = new $$service();
serve.id = "hello_wrongPath"; // wrong path,will return 404
serve.$get()
.then(function (data) {
console.log("~~~hi~~~");
console.log(data);
return data;
})
.catch(function (error) {
console.log("~~~error~~~");
console.log(error);
console.log(error.status); // --> 404
console.log(error.statusText); // --> "Not Found"
console.log(error.config.timeout); // --> 5000
console.log(error.config.method); // --> GET
console.log(error.config.url); // --> request url
console.log(error.headers("content-type"));// --> "text/plain"
return error.$promise;
})
.finally(function(data){
console.log("~~~finally~~~");
console.log(data); // --> undefined
});
De cette façon, vous ne pouvez attraper que status,statusText,timeout,method,headers(same with responseHeaders)
dans la réponse ERROR.
Si vous voulez voir les détails de la réponse dans success response, j'ai utilisé un intercepteur comme celui-ci:
ng.module("baseInterceptor", [])
.factory("baseInterceptor", ["$q", function ($q) {
return {
'request': function (config) {
console.info(config);
//set timeout for all request
config.timeout = 5000;
return config;
},
'requestError': function (rejection) {
console.info(rejection);
return $q.reject(rejection);
},
'response': function (response) {
console.log("~~interceptor response success~~");
console.log(response);
console.log(response.status);
console.log(response.config.url);
return response;
},
'responseError': function (rejection) {
console.log("~~interceptor response error~~");
console.log(rejection);
console.log(rejection.status);
return $q.reject(rejection);
}
};
}]);
puis ajoutez un intercepteur au module:
.config(["$httpProvider", function ($httpProvider) {
$httpProvider.interceptors.Push("baseInterceptor");
}])
Je pense que la bonne réponse est une combinaison des réponses de Bardiel et d'Ara.
Après avoir ajouté un intercepteur dans votre déclaration de ressource. Comme ça:
var resource = $resource(url, {}, {
get: {
method: 'GET'
interceptor: {
response: function(response) {
var result = response.resource;
result.$status = response.status;
return result;
}
}
}
});
Utilisez-le comme ci-dessous:
RestAPI.save()
.query(function(response) {
// This will return status code from API like 200, 201 etc
console.log(response.$status);
})
.$promise.catch(function(response) {
// This will return status code from server side like 404, 500 etc
console.log(response.status);
});
J'utilise AngularJS v1.5.6, et je le fais comme ceci (dans mon cas, j'ai mis la méthode "getData" dans un service):
function getData(url) {
return $q(function (resolve, reject) {
$http.get(url).then(success, error);
function success(response) {
resolve(response);
}
function error(err) {
reject(err);
}
});
}
puis dans le contrôleur (par exemple), appelez ça comme ceci:
function sendGetRequest() {
var promise = service.getData("someUrlGetService");
promise.then(function(response) {
//do something with the response data
console.log(response.data);
}, function(response) {
//do something with the error
console.log('Error status: ' + response.status);
});
}
Comme le dit la documentation, l'objet de réponse a les propriétés suivantes:
- data - {string | Object} - Le corps de la réponse transformé avec les fonctions de transformation.
- status - {numéro} - Code de statut HTTP de la réponse.
- headers - {function ([headerName])} - Fonction de lecture d'en-tête.
- config - {Object} - L'objet de configuration utilisé pour générer la demande.
- statusText - {string} - Texte d'état HTTP de la réponse.
Voir https://docs.angularjs.org/api/ng/service/$http
J'espère que ça aide!