I'm fairly new to Javascript promises, and running into an issue that I can't hunt down anything about via Google or Stack Exchange. When I refer to a function in a .then chained off a promise, I sometimes have to wrap that function in an anonymous function in order to stop it from automatically executing before the original promise is resolved. For example, if my code is
function deleteAdvertiser(advertiser) {
dialogService.Confirm(null, 'Delete')
.then(advertiserService.deleteAdvertiser(advertiser))
.then(getAdvertisers);
}
the call to advertiserService.deleteAdvertiser will automatically fire before I resolve the promise from the dialogService.Confirm. However, if I write it as
function deleteAdvertiser(advertiser) {
dialogService.Confirm(null, 'Delete')
.then(function () {
advertiserService.deleteAdvertiser(advertiser)
.then(getAdvertisers);
});
}
it behaves as expected: the advertiserService.deleteAdvertiser call doesn't happen until I resolve the dialogService.Confirm promise (in this case by clicking the "Delete" button inside my confirmation dialog).
The dialogService uses ngDialog's .openConfirm method, which returns a promise. I've verified that this promise is returning correctly. My best guess as to why this is happening is that my need to pass along an advertiser object from the UI (the function is initially called via an ng-click on a trash can button) means that I have to call advertiserService.deleteAdvertiser(advertiser)-- that is to say, with an argument passed in-- which in turn means that JS is executing that function call as soon as it reads it, rather than just storing the reference to use later when the initial promise is resolved.
Am I correct in my understanding of why the first code block doesn't work? Why does wrapping it in an anonymous function make the difference? And is there a correct (or at least better) way to chain these promises?
Thank you!
with an argument passed in, JS is executing that function call as soon as it reads it
Yes. When you pass an argument, and put () behind the function, you are calling it. You need to pass a function instead - just like you do .then(getAdvertisers) instead of .then(getAdvertisers()).
Notice that it doesn't need to be a function expression, you could use .bind as well:
dialogService.Confirm(null, 'Delete')
.then(advertiserService.deleteAdvertiser.bind(advertiserService, advertiser))
.then(getAdvertisers);
which is roughly equivalent to
dialogService.Confirm(null, 'Delete')
.then(function(confirmRes) {
return advertiserService.deleteAdvertiser(advertiser);
})
.then(getAdvertisers);
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