javascript - example - promesas en angular 6
AngularJS: devolviendo una promesa desde adentro. ¿Entonces? (3)
Tengo un servicio de usuarios. Me gustaría crear un método que utilice otro servicio que he creado. Hay dos métodos en este servicio. getUser()
y getCurrentUser()
. getCurrentUser()
utiliza el servicio inyectado que adquiere el UID. Utiliza el UID devuelto para ejecutar el método getUser()
. Mi problema es que no puedo obtener getCurrentUser()
para devolver la promesa del segundo nivel.
Esta pregunta es un poco difícil de explicar. Aquí está el código ...
svs.service("usersService", function($rootScope, $http, loginService, alertBoxService) {
var self = this;
self.getUser = function(identifier, column) {
if (typeof(column) === ''undefined'') column = "uid";
return $http.get($rootScope.api + "/getUser/" + identifier + "/" + column);
}
self.getCurrentUser = function() {
var currentUserPromise;
loginService.getCurrentUid().then(
function(response) {
if (response.data === "false") {
alertBoxService.trigger($rootScope.unexpectedApiResponse);
} else {
console.log(self.getUser(response.data));
currentUserPromise = self.getUser(response.data);
}
}, function(response) {
alertBoxService.trigger($rootScope.asyncFailed);
}
);
return currentUserPromise;
}
});
El problema aquí es que cuando se llama a la función getCurrentUser
, devuelve inmediatamente una variable undefined
. Esto se debe a que el servicio es asincrónico y para el momento en que se recibe la respuesta en el servicio, la llamada a la función ya habría devuelto una variable undefined
. Para evitar esto, puede agregar la llamada de return
dentro del loginService
.
Encadena las promesas, pero no te olvides de encadenar los rechazos también ...
self.getCurrentUser = function() {
return loginService.getCurrentUid().then(function(response) {
if (response.data === ''false'') {
alertBoxService.trigger($rootScope.unexpectedApiResponse);
return $q.reject(response); // convert into a rejection
}
return self.getUser(response.data); // chain the promise resolution
}, function(response) {
alertBoxService.trigger($rootScope.asyncFailed);
return $q.reject(response); // chain the rejections
});
}
Necesitarás inyectar el servicio $q
, por supuesto.
Como señaló gentilmente Bergi , también puede rechazar la promesa arrojando un error en lugar de usar $q.reject
, por ejemplo
throw response;
Para que una función asíncrona devuelva una promesa desde el interior de la devolución de llamada exitosa, debe regresar de la devolución de llamada que es el objeto prometido y luego regresar de la función principal para proporcionar la promesa a la persona que llama.
Prueba esto.
svs.service("usersService", function($rootScope, $http, loginService, alertBoxService) {
var self = this;
self.getUser = function(identifier, column) {
if (typeof(column) === ''undefined'') column = "uid";
return $http.get($rootScope.api + "/getUser/" + identifier + "/" + column);
}
self.getCurrentUser = function() {
return loginService.getCurrentUid().then(
function(response) {
if (response.data === "false") {
alertBoxService.trigger($rootScope.unexpectedApiResponse);
} else {
console.log(self.getUser(response.data));
return self.getUser(response.data);
}
}, function(response) {
alertBoxService.trigger($rootScope.asyncFailed);
}
);
}
});