-3

Struggling to return a AJAX Result Variable back to JavaScript

Note that the $.ajax call below is synchronous (async: false).

Ajax Call

function getState(callback) {
    $.ajax({
        url: 'getSearchState.php',
        data: { "state": callback },
        type: 'GET',
        async: false,
        success: function(result){
            alert(result);
        },
        error: function(result) {
        alert(result);
      }
    });
}

Ajax PHP

<?php
    // Database Setup and Query

while ($row = $xxxxx->fetch(PDO::FETCH_ASSOC)) {
    $StateVal = $row['State'];
}

return $StateVal;
?>

Javascript Calling the Function

var URL = District.trim();  
var StateURL = getState(URL);

It gets the URL vairable from the function just fine, but doesnt return anything.

Any help would be great!

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Frog82
  • 464
  • 1
  • 8
  • 25
  • 1
    And there is no `return` in `getState()` – Alex K. Sep 21 '16 at 14:58
  • 2
    I see `$stateVal` is an array so do `echo json_encode($StateVal);` return does something completely different. this will return the array as a JSONString. You cannot pass back a PHP array and hope to make sense of it in javascript – RiggsFolly Sep 21 '16 at 14:58
  • 1
    @slbetman: Nope, not this time. It's not asynchronous. – T.J. Crowder Sep 21 '16 at 14:58
  • 3
    `async: false,` is deprecated and will be removed. Don't use it! – A. Wolff Sep 21 '16 at 15:00
  • What should be the return? If I put result it comes up with "(index):187 Uncaught ReferenceError: result is not defined" – Frog82 Sep 21 '16 at 15:01
  • woops on the close. missed the async:false bit. – Marc B Sep 21 '16 at 15:01
  • 1
    Still, the problem is included in the question `doesnt return anything` - indeed. As @AlexK. pointed out, there is no `return`. The statement of the problem and the problem itself are already included in the entire premise. Does it really need to stay open? – VLAZ Sep 21 '16 at 15:05
  • Can't help but notice that in your PHP, you're looping through presumably-several rows, but only keeping the value of the **last** row's `State`. Just a side note. – T.J. Crowder Sep 21 '16 at 15:19
  • Woops missed that he was not actually creating an array correctly in the PHP – RiggsFolly Sep 21 '16 at 15:26

2 Answers2

2

There are problems with that code both client-side and server-side.

Client-side:

Your getState is never returning anything, so it's no surprise that you don't see anything other than undefined for StateURL.

Don't use synchronous ajax. It makes for horrible UX. But if you really, really want to keep using it, here's how you would:

function getState(state) {
    var result; // <=== Where we'll put our result
    $.ajax({
        url: 'getSearchState.php',
        data: {"state": state},
        type: 'GET',
        async: false,
        success: function(data) {
            // Remember the result;
            result = data;
        },
        error: function() {
            result = /*...whatever you want to use to signal an error */;
        }
    });

    // Return the result
    return result;
}

Note that I changed the name of the argument to state, since it's not a callback.

But again, don't use synchronous ajax. Instead, use a callback or promises.

Promise: $.ajax already returns a promise, so just return that directly:

function getState(state) {
    var result; // <=== Where we'll put our result
    $.ajax({
        url: 'getSearchState.php',
        data: {"state": state},
        type: 'GET',
        async: false,
        success: function(data) {
            // Remember the result;
            result = data;
        },
        error: function() {
            result = /*...whatever you want to use to signal an error */;
        }
    });

    // Return the result
    return result;
}

Note that I changed the name of the argument to state, since it's not a callback.

But again, don't use synchronous ajax. Instead, use a callback or promises.

Promise:

function getState(state) {
    return $.ajax({
        url: 'getSearchState.php',
        data: {"state": state},
        type: 'GET'
    });
}

Usage:

getState(URL)
    .done(function(StateURL) {
        // Use it
    })
    .fail(function() {
        // Failed
    });

Callback:

function getState(state, callback) {
    $.ajax({
        url: 'getSearchState.php',
        data: {"state": state},
        type: 'GET',
        success: function(data) {
            // Call the callbback with the result
            callback(data);
        },
        error: function() {
            // Call the callback with an error
            callback(/*...whatever you want to use tosignal an error */);
        }
    });
}

Usage:

getState(URL, function(StateURL) {
    // Use it, check for error
});

Server-side:

As RiggsFolly pointed out, you're returning a string from your PHP code. But that won't output it. To use it client-side, you need to output it (e.g., echo and similar). And to make it easily consumed by the JavaScript, you probably want to json_encode it to ensure that it's in a format JavaScript can understand:

echo json_encode($stateVal);

Then in your success (or done) function, use JSON.parse on it:

result = JSON.parse(data);
Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Great write up, I can see that the structure was all over the place! Thanks for that. However, I beleive it is working, but there is no data for the vairable in var StateURL = getState(URL); – Frog82 Sep 21 '16 at 15:09
  • 1
    See my [comment above](http://stackoverflow.com/questions/39620012/ajax-call-that-returns-javascript-variable#comment66545999_39620012) Everybody seems to have missed the obvious bit – RiggsFolly Sep 21 '16 at 15:11
  • surely though `$StateVal` is a single string rather than an array – Professor Abronsius Sep 21 '16 at 15:17
  • 1
    @T.J.Crowder That **is precisely** what my comment was supposed to convey. But you need to **`echo`** it and not **`return`** it and also `json_encode()` it **which he is not doing** . Look the **PHP** part of the question – RiggsFolly Sep 21 '16 at 15:21
  • I admit I assumed he was creating an array and missed that he had screwed that up as well – RiggsFolly Sep 21 '16 at 15:27
  • @RiggsFolly: How strange! I could have **sworn** I saw `json_encode` in the question. Just looked, it's not there, [it's never been there](http://stackoverflow.com/posts/39620012/revisions), what was I...? Sorry, and thanks! (I must have -- bizarrely -- conflated your comment with the question.) – T.J. Crowder Sep 21 '16 at 15:34
  • @RamRaider Yes it is, but of course it should really be an array based on the loop unloading multiple rows from the database. Unless of course OP has coded `->fetch()` in a loop for no other reason than he saw an example using `while` I note he does not bother to show us the query that generates the data from his database so I could be wrong here – RiggsFolly Sep 21 '16 at 15:41
  • @RiggsFolly: But I suspect you're not (wrong). You're welcome to take as much of the above as you like and include it in an answer that also does a thorough job addressing the PHP issues. If you do, ping me and I'll delete the above in favor of that. – T.J. Crowder Sep 21 '16 at 15:43
  • @T.J.Crowder Simpler to add that bit to your answer. The javascript stuff may well turn out to have been a red herring, but it really should stay in an answer somewhere. I am in the process of trying to integrate said knowledge into my thick head as we speak – RiggsFolly Sep 21 '16 at 15:48
  • Bravo Guys, it is finally returning something even if it is null, great write up though – Frog82 Sep 22 '16 at 07:45
-4

this is jQuery and in this case you can specify context and in success function set variables on that context.... a bit crude solution but it will works. Also take a look on arrow functions and promises from ES6, it can help you a lot and give you new perspective about whole problem.

And one main thing!! Ajax is async by default so you need somehow notify your StateURL when data will be ready (here again promise at you service)

jan smrz
  • 31
  • 2
  • 2