gudepier
gudepier

Reputation: 3612

How to wait the return of a Callback function?

How to implement that use case properly: after the customer has confirmed an action I want to display a waiting screen until the callback function has been performed completely...

I've done the following but the REST call is performed after that the srv.hideLoadingScreen() has been called... :-/

DialogService:

srv.onApprove = function(callback){
    srv.displayLoadingScreen();
    callback();
    srv.hideLoadingScreen();
};

Controller:

ctrl.showConfirmModal = function(){
    //...
    if(approved){
        DialogService.onApprove(function(){
            ctrl.performAction();
        });
    }
};

ctrl.performAction = function(){
    console.log('performAction');
    if(angular.isDefined(ctrl.selectedNumberList)){
        var numberList = {
            nbList: ctrl.selectedNumberList
        };
        MyService.launch(numberList, function(response){ // REST call
            console.log('call ok');
        }, function(error){
            console.log('error');
        });
    }
};



Update: Currently I've chose this solution that avoids a callback of the callback: Close the waiting panel in the ctr.perfomAction()

MyService.launch(numberList, function(response){ // REST call
    console.log('call ok');
    DialogService.hideLoadingScreen();
}, function(error){
    console.log('error');
    DialogService.hideLoadingScreen();
});

Upvotes: 1

Views: 262

Answers (2)

Lucas
Lucas

Reputation: 10303

Use Angular-busy. This way should work for you:

APPLY

  1. bower install angular-busy --save
  2. Add dist/angular-busy.js and dist/angular-busy.css to your index.html
  3. Add cgBusy as a module dependency for your module.
  4. angular.module('your_app', ['cgBusy']);

CONTROLLER

   $scope.myPromise = MyService.launch(numberList, function(response){ // REST call...

PARTIAL

        <div cg-busy="{promise:myPromise,
                       message:'Loading',
                       backdrop:false,
                       templateUrl:'myAwesomeTemplate.html',
                       delay:300,
                       minDuration:700} ">
         </div>

EDIT FOR YOUR COMMENT:

What about something like this?

 MyService.launch(numberList, function(response){
  ----->     $scope.myPromise = console.log('call ok');     <--------
        }, function(error){
            console.log('error');
        });

Upvotes: 0

David East
David East

Reputation: 32604

You can just use the $http service to return a Promise.

Asynchronous actions aren't returned until they are completed and the call stack is clear. Since we'll leave scope before they are returned you can use a Promise to ensure you get the value back.

app.service('MyService', function($http) {
  this.launch = function launch() {
    return $http({ method: 'GET', url: '/endpoint' });
  };
}

app.controller('MyCtrl', function(MyService) {
  MyService.launch()
     .then(function(response) {

     });
});

The same can also be achieved with the $q service to return a promise for any type asynchronous call.

Upvotes: 1

Related Questions