In angular application you can often see a code logically similar to:
function SubmitController($http) {
var vm = this;
vm.inProgress= false;
vm.resolved = false;
vm.rejected = false;
vm.submitData = function() {
vm.inProgress = true;
return $http.post('....')
.then(function() {
vm.resolved = true;
//Doing something usefull
})
.catch(function() {
vm.rejected = true;
})
.finally(function() {
vm.inProgress = false;
});
}
}
And a template<button ng-disabled='vm.inProgress' ng-click='vm.submitData()'>Submit</button>
<span class='ng-hide' ng-show='vm.inProgress'>Submitting...</span>
<span class='ng-hide' ng-show='vm.resolved'>Submitted succsssfully!</span>
<span class='ng-hide' ng-show='vm.rejected'>Failed to submit!</span>
Looks familiar, isn't it? And it's getting even more messy if you have several actions like this. So following the DRY principal I came across with a very simple and flexible solution, just keep reading :)The Filter
The filter is applied on the result of the action that returns promise and transforms it to a status object. The object has inProgress, resolved and rejected properties. The filter will be updating those properties on resolve or reject cases. So here is the code:
function promiseStatus() {
return function(promise) {
var status = {
inProgress: true,
resolved: false,
rejected: false
};
promise
.then(function() {
status.resolved = true;
})
.catch(function() {
status.rejected = true;
})
.finally(function() {
status.inProgress = false;
});
return status;
}
}
All you need to do is adjust your template like this
<button
ng-disabled='status.inProgress'
ng-click='status = (vm.submitData() | promiseStatus)'>Submit</button>
<span class='ng-hide' ng-show='status.inProgress'>Submitting...</span>
<span class='ng-hide' ng-show='status.resolved'>Submitted succsssfully!</span>
<span class='ng-hide' ng-show='status.rejected'>Failed to submit!</span>
As you can see the template is pretty match the same but your controller is crystal clear now:
Full source code can be found on Github.
function SubmitController($http) {
var vm = this;
vm.submitData = function() {
return $http.post('....')
.then(function() {
//Doing something usefull
});
}
}
Full source code can be found on Github.
No comments:
Post a Comment