When dealing with a chained promise and facing rejection in any of the promises, I require an async operation to be performed (such as retrieving a translated error message). Since chaining on rejection seems impossible when there is already a chained promise on success, I tried nesting the async calls. However, I encountered an issue where I am not receiving the resolved promise back from
deferred.reject(deferredRejection.promise);
below. Any guidance would be greatly appreciated!
login: function(email, password) {
var deferred = $q.defer();
AuthService.login(email, password).then(function(response) {
var user = {
'accountToken': response.accountToken,
'email': response.username,
'onboarded': response.onboarded,
'verified': response.verified
};
return SyncStorageService.write(SyncStorageService.storageKeys.user,
user);
}, function(error) {
// login failed
var deferredRejection = $q.defer();
$translate('ALERTS.LOGIN_FAILED').then(function(translatedValue) {
deferredRejection.resolve(translatedValue);
});
deferred.reject(deferredRejection.promise);
}).then(function(data) {
deferred.resolve(data);
}, function(error) {
// saving data failed
var deferredRejection = $q.defer();
$translate('ALERTS.UNKNOWN').then(function(translatedValue) {
deferredRejection.resolve(translatedValue);
});
deferred.reject(deferredRejection.promise);
});
return deferred.promise;
}
Updated Solution:
Following the advice provided, I have refactored the code as shown below:
login: function(email, password) {
return AuthService.login(email, password).then(function(response) {
return {
'accountToken': response.accountToken,
'email': response.username,
'onboarded': response.onboarded,
'verified': response.verified
};
}).then(function(data) {
return SyncStorageService.write(SyncStorageService.storageKeys.user,
data);
});
}
Additional Information:
- Both
AuthService.login
andSyncStorageService.write
now reject promises with anError
object (e.g.
), which will propagate through thenew Error('ALERT.ERROR_MESSAGE');
login
method to the controller (instead of handling translation at the service level) - The calling controller for the
login
method includes.then()
and.catch()
blocks - if caught in a.catch()
, theError.message
passed will be translated and displayed.