最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do you return a boolean value based on the result of a promise? - Stack Overflow

programmeradmin3浏览0评论

Working with an AngularJS app (1.4.3), I want a controller to make a call to a method on a service, which should return a boolean value.

Under the hood, the service used to make a call to $window.confirm(), and then just return the result. I am trying to switch the implementation to use Angular Material's $mdDialog.confirm() API, but this returns a promise.

The problem I am running into is that there is no way to return true or false directly from my service without changing the code in my controller to expect a promise. The whole purpose of extracting this method into a service was so that the controller could be separated from the implementation details of the call, and I would consider using a promise (ie, a future boolean) vs. a straight boolean to be an implementation detail.

Here is some code to illustrate: In the controller:

function confirmDeleteDevice() {
    if (notificationService.confirm('Are you sure you want to delete the device?')) {
        deleteDevice();
    }
}

Old function in 'notificationService':

function confirm(message) {
    return $window.confirm(message);
}

New function in notificationService that will not work as expected with the controller code above:

function confirm(message) {
    var confirm = $mdDialog.confirm()
        .title(message)
        .ariaLabel(message)
        .ok('Yes')
        .cancel('No');
    return $mdDialog.show(confirm).then(function() {
        return true;
    }, function() {
        return false;
    });
}

Without changing the controller code to rely on the implementation detail of using a promise, how do I get a boolean value out of my service method? The code above will always execute "deleteDevice()" because the new notificationService.confirm() will return the unresolved promise, which apparently qualifies as a truthy value for the if clause.

I'm definitely no expert on promises, and I understand this isn't exactly how they are expected to be used, but I'd really rather not tie the controller down to using a promise. Is this even possible given the "async" nature of promises?

UPDATE: I definitely looked before I posted and could find nothing, but this just showed up in the "related questions" feed, so I see now my question was a duplicate. The answers there are pretty helpful.

Working with an AngularJS app (1.4.3), I want a controller to make a call to a method on a service, which should return a boolean value.

Under the hood, the service used to make a call to $window.confirm(), and then just return the result. I am trying to switch the implementation to use Angular Material's $mdDialog.confirm() API, but this returns a promise.

The problem I am running into is that there is no way to return true or false directly from my service without changing the code in my controller to expect a promise. The whole purpose of extracting this method into a service was so that the controller could be separated from the implementation details of the call, and I would consider using a promise (ie, a future boolean) vs. a straight boolean to be an implementation detail.

Here is some code to illustrate: In the controller:

function confirmDeleteDevice() {
    if (notificationService.confirm('Are you sure you want to delete the device?')) {
        deleteDevice();
    }
}

Old function in 'notificationService':

function confirm(message) {
    return $window.confirm(message);
}

New function in notificationService that will not work as expected with the controller code above:

function confirm(message) {
    var confirm = $mdDialog.confirm()
        .title(message)
        .ariaLabel(message)
        .ok('Yes')
        .cancel('No');
    return $mdDialog.show(confirm).then(function() {
        return true;
    }, function() {
        return false;
    });
}

Without changing the controller code to rely on the implementation detail of using a promise, how do I get a boolean value out of my service method? The code above will always execute "deleteDevice()" because the new notificationService.confirm() will return the unresolved promise, which apparently qualifies as a truthy value for the if clause.

I'm definitely no expert on promises, and I understand this isn't exactly how they are expected to be used, but I'd really rather not tie the controller down to using a promise. Is this even possible given the "async" nature of promises?

UPDATE: I definitely looked before I posted and could find nothing, but this just showed up in the "related questions" feed, so I see now my question was a duplicate. The answers there are pretty helpful.

Share Improve this question edited May 23, 2017 at 12:08 CommunityBot 11 silver badge asked Sep 4, 2015 at 19:20 SeanSean 4981 gold badge5 silver badges13 bronze badges 1
  • 1 No, asynchrony is not an implementation detail, as it does change the control flow of the caller a lot. And no, there's no way to get the boolean out of the promise synchronously. Just make your controller expect asynchronous results - and you can make it an implementation detail that its synchronous under the hood. – Bergi Commented Sep 4, 2015 at 22:03
Add a ment  | 

1 Answer 1

Reset to default 2

You will have to make your condition async as well, chaining through the promise.

i.e

notificationService.confirm('...').then(function(confirmation){
     if(confirmation) {
         deleteDevice();
     }
});

and you really would not need to have catch and return false unless you need to really track the return value since dialog already resolves/rejects the promise based on cancel or Ok, i.e below blocks wont be needed.

   .then(function() {
        return true;
    }, function() {
        return false;
    });

So

function confirm(message) {
    var confirm = $mdDialog.confirm()
        .title(message)
        .ariaLabel(message)
        .ok('Yes')
        .cancel('No');

    return $mdDialog.show(confirm);
}

and just:

notificationService.confirm('...').then(deleteDevice);
发布评论

评论列表(0)

  1. 暂无评论