Lo hago como sugiere Bradley Braithwaite en su 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;
});
}])
Puntos clave:
La función de resolución se enlaza con la función .then en nuestro controlador, es decir, todo está bien, por lo que podemos mantener nuestra promesa y resolverla.
La función de rechazo se enlaza con la función .catch en nuestro controlador, es decir, algo salió mal, por lo que no podemos cumplir nuestra promesa y debemos rechazarla.
Es bastante estable y seguro y si tienes otras condiciones para rechazar la promesa siempre puedes filtrar tus datos en la función de éxito y llamar deferred.reject(anotherReason)
con el motivo del rechazo.
Como sugirió Ryan Vice en los comentarios , esto puede no ser visto como útil a menos que juegues un poco con la respuesta, por así decirlo.
Porque success
y error
están en desuso desde 1.4, tal vez sea mejor usar los métodos de promesa regulares then
ycatch
y transformar la respuesta dentro de esos métodos y devolver la promesa de que la respuesta transformada.
Estoy mostrando el mismo ejemplo con ambos enfoques y un tercer enfoque intermedio:
success
y error
enfoque ( success
y error
devolver una promesa de una respuesta HTTP, por lo que necesitamos la ayuda de $q
para devolver una promesa de datos):
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
y catch
enfoque (esto es un poco más difícil de probar, debido al lanzamiento):
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;
}
Sin embargo, hay una solución a mitad de camino (de esta manera puede evitar el throw
y de todos modos probablemente necesitará usar $q
para simular el comportamiento de la promesa en sus pruebas):
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;
}
Cualquier tipo de comentarios o correcciones son bienvenidos.
success()
,error()
yfinally()
combinado concatch()
? O tengo que usarthen(successFunction, errorFunction).catch(exceotionHandling).then(cleanUp);