2

I have a dialog with a button. Once clicked the button calls an async method which returns true or false depending on whether the posted data is valid or not. The click event calls the method below. Now, the problem is that closeDialog is called before the callback function is executed!! How can I make this work?

Thanks

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         closeResult = true;
      else
         closeResult = false;
   }); 

   if (closeResult !== false) {
       this.closeDialog();
   }
},
Hank Rearden
  • 87
  • 1
  • 1
  • 10
  • put `this.closeDialog()` inside the callback (first `if` condition). You also need to bind `this`. –  Jul 04 '16 at 13:13
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Andreas Jul 04 '16 at 13:15
  • https://jsfiddle.net/rayon_1990/tzzze97s/ – Rayon Jul 04 '16 at 13:17

4 Answers4

1

You should look at using promise. JQuery Ajax calls natively return a Promise.

EG:

$.ajax(ajaxObj).success(function(resp) { console.log('I have completed');});

place the dialog close in the success or failure part of the call.

Rhys Bradbury
  • 1,699
  • 13
  • 24
1

Based on your code snippet it should look like so:

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         this.closeDialog();

   }); 
},

In your version this code

if (closeResult !== false) {
    this.closeDialog();
}

gets called before callback for asyncThing is called. That's why the dialog closeDialog is called

Alexey
  • 980
  • 5
  • 12
0

The function withing asyncThing is called when(whenever that might be) the asynchronous call is finished. So this will not be interpreted line-by-line.

Move the latter if question to callback function and it will be fine.

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
       if (result)
           closeResult = true;
       else
           closeResult = false;
    if (closeResult !== false) {
       this.closeDialog();
    }
  });
},
Rouz
  • 1,247
  • 2
  • 15
  • 37
  • @Hank To what is [`this`](http://stackoverflow.com/a/20279485/6445533) bound, when the callback is finally invoked? This doesn't work. –  Jul 04 '16 at 13:35
  • I think this is a part of something bigger. Also i would suggest if(result) { this.closeDialog(); } It would have one if less and one variable less. But that was not the question – Rouz Jul 04 '16 at 13:40
0

It's because async part of this code is in callback function. And you call close dialog in a sync part, which runs right after the request is sent. Just move The call to the callback.

As, was mentioned, you also need to handle this inside the callback function, as js determines this at runtime. So it's not always the reference to your object.

One way is to cache this in another variable outside the callback.

close: function (srcCmd) {
   var self = this;
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         closeResult = true;
         self.closeDialog();
      else
         closeResult = false;
   }); 
},

Another way is to use one of the binding methods (.bind, .call, .apply):

close: function (srcCmd) {
   var closeResult = true;
   asyncThing(function(result) {
      if (result)
         closeResult = true;
         this.closeDialog();
      else
         closeResult = false;
   }.bind(this)); 
},

Also there's a Promise pattern for handling async. But it is harder to use properly.

Anton Pudikov
  • 281
  • 1
  • 6