Je le fais comme le suggère Bradley Braithwaite dans son blog :
app
.factory('searchService', ['$q', '$http', function($q, $http) {
var service = {};
service.search = function search(query) {
// We make use of Angular's $q library to create the deferred instance
var deferred = $q.defer();
$http
.get('http://localhost/v1?=q' + query)
.success(function(data) {
// The promise is resolved once the HTTP call is successful.
deferred.resolve(data);
})
.error(function(reason) {
// The promise is rejected if there is an error with the HTTP call.
deferred.reject(reason);
});
// The promise is returned to the caller
return deferred.promise;
};
return service;
}])
.controller('SearchController', ['$scope', 'searchService', function($scope, searchService) {
// The search service returns a promise API
searchService
.search($scope.query)
.then(function(data) {
// This is set when the promise is resolved.
$scope.results = data;
})
.catch(function(reason) {
// This is set in the event of an error.
$scope.error = 'There has been an error: ' + reason;
});
}])
Points clés:
La fonction de résolution est liée à la fonction .then de notre contrôleur, c'est-à-dire que tout va bien, nous pouvons donc tenir notre promesse et la résoudre.
La fonction de rejet est liée à la fonction .catch de notre contrôleur, c'est-à-dire que quelque chose s'est mal passé, nous ne pouvons donc pas tenir notre promesse et devons la rejeter.
C'est assez stable et sûr et si vous avez d'autres conditions pour rejeter la promesse, vous pouvez toujours filtrer vos données dans la fonction de réussite et appeler deferred.reject(anotherReason)
avec la raison du rejet.
Comme Ryan Vice l'a suggéré dans les commentaires , cela peut ne pas être considéré comme utile à moins que vous ne manipuliez un peu la réponse, pour ainsi dire.
Parce que success
et error
sont obsolètes depuis la version 1.4, il est peut-être préférable d'utiliser les méthodes de promesse régulières then
etcatch
et transformer la réponse dans ces méthodes et retourner la promesse de cette réponse transformée.
Je montre le même exemple avec les deux approches et une troisième approche intermédiaire:
success
et error
approche ( success
et error
retourne une promesse de réponse HTTP, nous avons donc besoin de l'aide de $q
pour renvoyer une promesse de données):
function search(query) {
// We make use of Angular's $q library to create the deferred instance
var deferred = $q.defer();
$http.get('http://localhost/v1?=q' + query)
.success(function(data,status) {
// The promise is resolved once the HTTP call is successful.
deferred.resolve(data);
})
.error(function(reason,status) {
// The promise is rejected if there is an error with the HTTP call.
if(reason.error){
deferred.reject({text:reason.error, status:status});
}else{
//if we don't get any answers the proxy/api will probably be down
deferred.reject({text:'whatever', status:500});
}
});
// The promise is returned to the caller
return deferred.promise;
};
then
et catch
approche (c'est un peu plus difficile à tester, à cause du lancer):
function search(query) {
var promise=$http.get('http://localhost/v1?=q' + query)
.then(function (response) {
// The promise is resolved once the HTTP call is successful.
return response.data;
},function(reason) {
// The promise is rejected if there is an error with the HTTP call.
if(reason.statusText){
throw reason;
}else{
//if we don't get any answers the proxy/api will probably be down
throw {statusText:'Call error', status:500};
}
});
return promise;
}
Il existe cependant une solution à mi-chemin (de cette façon, vous pouvez éviter throw
et de toute façon vous devrez probablement l'utiliser $q
pour vous moquer du comportement de promesse dans vos tests):
function search(query) {
// We make use of Angular's $q library to create the deferred instance
var deferred = $q.defer();
$http.get('http://localhost/v1?=q' + query)
.then(function (response) {
// The promise is resolved once the HTTP call is successful.
deferred.resolve(response.data);
},function(reason) {
// The promise is rejected if there is an error with the HTTP call.
if(reason.statusText){
deferred.reject(reason);
}else{
//if we don't get any answers the proxy/api will probably be down
deferred.reject({statusText:'Call error', status:500});
}
});
// The promise is returned to the caller
return deferred.promise;
}
Tout type de commentaire ou de correction est le bienvenu.
success()
,error()
etfinally()
combiné aveccatch()
? Ou dois-je utiliserthen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);