17

How do I make function out of this?

         //check if station is alive
         $.ajax({
           url: "lib/grab.php",
           data: "check_live=1&stream_url="+valueSelected,
           type: "GET",
               success: function (resp) {
                 if (resp == 1) {
                   play_this(valueSelected);
                 } else {
                   //
                 }
               },
               error: function (e) {
                 console.dir(e);
               }
         });

I thought I could do something like this:

function is_alive(valueSelected) {
result = false;
             //check if station is alive
             $.ajax({
               url: "lib/grab.php",
               data: "check_live=1&stream_url="+valueSelected,
               type: "GET",
                   success: function (resp) {
                     if (resp == 1) {
                       result = true;
                     } else {
                       //
                     }
                   },
                   error: function (e) {
                     console.dir(e);
                   }
             });
return result;
}

But obviously due to asynchronous nature of ajax call, result always returns false.

What is the trick of dealing with this situation?

Seems to work:

        //check if station is alive
        function is_alive(url) {
          //
          var result = false;
          //
          return $.ajax({
            url: "lib/grab.php",
            data: "check_live=1&stream_url="+url,
            type: "GET",
                success: function (resp) {
                  if (resp == 1) {
                    //
                    result = true;
                    //
                  }
                },
                error: function (e) {
                  console.dir(e);
                }
          }).then(function() {
            return $.Deferred(function(def) {
              def.resolveWith({},[result,url]);
            }).promise();
          });
        }

And call it like this:

    //Change song on select, works both for fav and station lists
    $(document).on("click", ".ui-listview li a", function(){
      var valueSelected = $(this).data("station-url");
      //
      is_alive(valueSelected).done(function(result,url){
          if (result) {
            //
            play_this(valueSelected);
            //
          }
      });
    });
  • set `async: false` in your ajax call – JFK Oct 10 '13 at 17:01
  • 4
    You shouldn't make it synchronous if it all possible. Synchronous AJAX calls block anything else going on in the browser. Ideally you should consider returning a promise from your function and then have whatever calls that function act on the returned promise. – Michael Mior Oct 10 '13 at 17:03
  • @MichaelMior can you extrapolate on promise? i like that way better than making ajax call sync. –  Oct 10 '13 at 17:07
  • it will freeze your browser – Arun Killu Oct 10 '13 at 17:07
  • @showdev Solutions here are better though! –  Oct 10 '13 at 17:11
  • @ArunKillu The simplest way to go about this is to simply return the result of `$.ajax(...).promise()` from your function. Then when you call the function you would call it like `is_alive(foo).then(function(data) { ... })` – Michael Mior Oct 11 '13 at 05:20

2 Answers2

11

You don't have to make it synchronous to make it a useful function.

function is_alive(valueSelected) {
    //check if station is alive
    return $.ajax({
        url: "lib/grab.php",
        data: "check_live=1&stream_url=" + valueSelected,
        type: "GET",
        error: function (e) {
            console.dir(e);
        }
    });
}

is_alive(somevalue).then(function(result){
    console.log(result, somevalue);
});
Kevin B
  • 94,570
  • 16
  • 163
  • 180
  • First time I hear about promise(). Gonna read about that. And thanks! –  Oct 10 '13 at 17:14
  • p.s. I couldn't make it work as you wrote it. So I updated my post to include answer. What do you think? I was receiving error about resp not being defined. When I defined it outside ajax it was always returning false. –  Oct 10 '13 at 17:39
  • I feel I shouldn't upvote this, because it doesn't actually answer the original question. On the other hand, this is exactly the answer I believe *should* be given, so... have some rep. :p – cloudfeet Oct 10 '13 at 17:42
  • @cloudfeet actually this is exactly what I wanted to know, I simply couldn't come up with a better title. –  Oct 10 '13 at 17:47
  • @KevinB if I don't define it inside function outside ajax, than I get js error in console: resp not defined. –  Oct 10 '13 at 17:49
  • @KevinB I updated my post to show exactly what I'm doing now, and it works. But if I replace this def.resolveWith({},[result,url]); with def.resolveWith({},[resp,url]); I get undefined variable problem. –  Oct 10 '13 at 18:13
  • @KevinB this is live: http://mac.idev.ge:800/radio/ –  Oct 10 '13 at 18:14
  • If I copy your code directly, I get Uncaught ReferenceError: resp is not defined error. Please take a look at live site, it has your code line to line. http://mac.idev.ge:800/radio/ –  Oct 10 '13 at 20:00
  • @KevinB sure, here it is: http://pastebin.com/CbMptKit, this errors out. I could make jsfiddle but my ajax doesn't work there. –  Oct 10 '13 at 20:54
9

You can supply the async: false option

function is_alive(valueSelected) {
     result = false;
             //check if station is alive
             $.ajax({
               async: false,
               url: "lib/grab.php",
               data: "check_live=1&stream_url="+valueSelected,
               type: "GET",
                   success: function (resp) {
                     if (resp == 1) {
                       result = true;
                     } else {
                       //
                     }
                   },
                   error: function (e) {
                     console.dir(e);
                   }
             });
return result;
}
Cillier
  • 1,021
  • 9
  • 8
  • I upvote cause you actually answered directly my question. But other answers seem like a better way to go. –  Oct 10 '13 at 17:06
  • Thanks ! Yes, I believe promises are the better way to go. Blocking the main thread is probably a "bad thing" – Cillier Oct 10 '13 at 17:16
  • After an hour of googling, this is the only answer that has worked for me. Thankyou. – David Klempfner May 18 '20 at 01:52