I have this confirmation in AngularJS that takes two callbacks: one if the user clicked Yes and another one if the user clicked No on a dialog box.
I need to ask the user first if he is done with the operation and, if he replies yes, I need to also ask if he wants to add the user as a manager. Regardless of the response for the two questions, I need to persist the data.
So I have this horrible, callback hell infested code to handle the branches I mentioned above:
$scope.promptAndSave = function() {
// first question
$scope.confirmation.display("Confirmation", "Did you finish working on this Reference Check?", function() {
// handles Yes for first question
$scope.referenceCheck.finished = true;
var manager_name = $scope.referenceCheck.first_name + " " + $scope.referenceCheck.last_name;
$scope.confirmation.display("Add new Manager", "Do you want to add <b>" + manager_name + "</b> as a new manager to your database?", function() {
// handles Yes for second question
$scope.referenceCheck.add_manager = true;
$scope.saveReferenceCheck();
}, function() {
// handles No for second question
$scope.saveReferenceCheck();
});
}, function() {
// handles No for first question
$scope.saveReferenceCheck();
});
};
Is this something that can potentially be resolved using promises? Or would any other, more generic JS technique that would fit this better?
I understand AngularJS provides $q, would that help here? How would the code above look when converted to promises?
EDIT
So confirmation is a local object on my $scope
, like this:
$scope.confirmation = {
visible: false,
title: "",
prompt: "",
yes: function() {
this.visible = false;
this.yesHandler();
},
no: function() {
this.visible = false;
this.noHandler();
},
display: function(title, prompt, yesHandler, noHandler) {
this.title = title;
this.prompt = prompt;
this.yesHandler = yesHandler;
this.noHandler = noHandler;
this.visible = true;
}
};
And I have template HTML code that interacts with the object to display the prompt:
<div id="confirmationForm" ng-show="confirmation.visible">
<div class="form-title">{{ confirmation.title }}</div>
<div class="form-body">
<div class="message" ng-bind-html-unsafe="confirmation.prompt"></div>
<div class="actions">
<span>
<button ng-click="confirmation.yes()">Yes</button>
<button ng-click="confirmation.no()">No</button>
</span>
<img src="/assets/spinner.gif" ng-show="confirmation.busy">
</div>
</div>
</div>
EDIT 2
With some help, I managed to put this together: http://jsfiddle.net/LJr5z/1/
EDIT 3
And to finish, $q doesn't support finally
in Angular 1.0.3, so here's the JSFiddle for the last version, with AngularJS 1.2 - http://jsfiddle.net/LJr5z/3/
So inject $q
and try this.
$scope.confirmation = {
visible: false,
title: "",
prompt: "",
yes: function() {
this.visible = false;
this.dfd.resolve();
},
no: function() {
this.visible = false;
this.dfd.reject();
},
display: function(title, prompt) {
this.dfd = $q.defer();
this.title = title;
this.prompt = prompt;
this.visible = true;
return this.dfd.promise;
}
};
To call it:
$scope.confirmation.display('title', 'prompt')
.then(function() {
// return another promise here, yes clicked
}, function() {
// no clicked
})
.then(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With