56

I have some problem using ajax.

How can I assign all result from ajax into outside variable ?

I google it up and found this code..

var return_first = (function () {
    var tmp = null;
    $.ajax({
        'async': false,
        'type': "POST",
        'global': false,
        'dataType': 'html',
        'url': "ajax.php?first",
        'data': { 'request': "", 'target': arrange_url, 'method': method_target },
        'success': function (data) {
            tmp = data;
        }
    });
    return tmp;
});

but not work for me..

Can anybody tell what is wrong about that code ?

Mohd Shahril
  • 2,257
  • 5
  • 25
  • 30
  • it will make request into "ajax.php?first" with post data, if data correct, then will print out "OK", if not then "NOT OK", and i want those result string to be assign to return_first variable.. – Mohd Shahril May 29 '13 at 04:11
  • 1
    The call is asynchronous, `tmp` will never fill because it will execute immediately, you need to use `deferred` or `promise` objects here. – Ohgodwhy May 29 '13 at 04:18
  • 3
    @Ohgodwhy - he has `'async': false` in `ajax` options. – Igor May 29 '13 at 04:20
  • https://stackoverflow.com/questions/22233650/jquery-nested-ajax-calls-formatting – RationalRabbit Aug 06 '21 at 06:28

7 Answers7

72

You are missing a comma after

'data': { 'request': "", 'target': 'arrange_url', 'method': 'method_target' }

Also, if you want return_first to hold the result of your anonymous function, you need to make a function call:

var return_first = function () {
    var tmp = null;
    $.ajax({
        'async': false,
        'type': "POST",
        'global': false,
        'dataType': 'html',
        'url': "ajax.php?first",
        'data': { 'request': "", 'target': 'arrange_url', 'method': 'method_target' },
        'success': function (data) {
            tmp = data;
        }
    });
    return tmp;
}();

Note () at the end.

Igor
  • 15,833
  • 1
  • 27
  • 32
45

This is all you need to do:

var myVariable;

$.ajax({
    'async': false,
    'type': "POST",
    'global': false,
    'dataType': 'html',
    'url': "ajax.php?first",
    'data': { 'request': "", 'target': 'arrange_url', 'method': 'method_target' },
    'success': function (data) {
        myVariable = data;
    }
});

NOTE: Use of "async" has been depreciated. See https://xhr.spec.whatwg.org/.

NightOwl888
  • 55,572
  • 24
  • 139
  • 212
joshuahealy
  • 3,529
  • 22
  • 29
  • 6
    The async: false solved my problem. Without it, I can't store it to a variable. – Ansjovis86 Apr 22 '17 at 11:41
  • @Ansjovis86, the same is true for me. Do you have any idea why that is the case? – tim_stuff Jan 10 '18 at 18:40
  • 2
    @tim_stuff Well I guess when it is async the code will continue without having received a response from the server. This would mean that you're variable is being called without it being there. When doing it synchronous the code will only continue when it has received the response from the server. – Ansjovis86 Jan 15 '18 at 12:30
30

Using 'async': false to prevent asynchronous code is a bad practice,

Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. https://xhr.spec.whatwg.org/

On the surface setting async to false fixes a lot of issues because, as the other answers show, you get your data into a variable. However, while waiting for the post data to return (which in some cases could take a few seconds because of database calls, slow connections, etc.) the rest of your Javascript functionality (like triggered events, Javascript handled buttons, JQuery transitions (like accordion, or autocomplete (JQuery UI)) will not be able to occur while the response is pending (which is really bad if the response never comes back as your site is now essentially frozen).

Try this instead,

var return_first;
function callback(response) {
  return_first = response;
  //use return_first variable here
}

$.ajax({
  'type': "POST",
  'global': false,
  'dataType': 'html',
  'url': "ajax.php?first",
  'data': { 'request': "", 'target': arrange_url, 'method': method_target },
  'success': function(data){
       callback(data);
  },
});
Lee Curran
  • 19
  • 6
Zahra Ghaed
  • 301
  • 3
  • 3
  • Sadly, this does appear to be the best answer available. I say sadly because being forced to use a global variable like that is reason #7633 to dislike javascript. – EGP Jan 22 '20 at 01:50
  • 1
    Agreed, this worked perfect and resolved my problem :) There are very few programs I create that do not include global variables, so its somewhat normal for me. – Tom aka Sparky Feb 17 '20 at 06:31
  • When dealing with client-side JS I've found it pretty difficult to avoid global variables entirely, and it seems most people find that difficult. So I would submit best practice is to use as few as possible but use them where you need them. If you end up with one or two you're doing it right. The way I've found to avoid globals is to use Axios to make my calls. – Andrew May 06 '20 at 19:12
0

So this is long after the initial question, and technically it isn't a direct answer to how to use Ajax call to populate exterior variable as the question asks. However in research and responses it's been found to be extremely difficult to do this without disabling asynchronous functions within the call, or by descending into what seems like the potential for callback hell. My solution for this has been to use Axios. Using this has dramatically simplified my usages of asynchronous calls getting in the way of getting at data.

For example if I were trying to access session variables in PHP, like the User ID, via a call from JS this might be a problem. Doing something like this..

async function getSession() {
 'use strict';
 const getSession = await axios("http:" + url + "auth/" + "getSession");
 log(getSession.data);//test
 return getSession.data;
}

Which calls a PHP function that looks like this.

public function getSession() {
 $session = new SessionController();
 $session->Session();
 $sessionObj = new \stdClass();
 $sessionObj->user_id = $_SESSION["user_id"];
 echo json_encode($sessionObj);
}

To invoke this using Axios do something like this.

getSession().then(function (res) {
 log(res);//test
 anyVariable = res;
 anyFunction(res);//set any variable or populate another function waiting for the data
});

The result would be, in this case a Json object from PHP.

{"user_id":"1111111-1111-1111-1111-111111111111"}

Which you can either use in a function directly in the response section of the Axios call or set a variable or invoke another function.

Proper syntax for the Axios call would actually look like this.

getSession().then(function (res) {
 log(res);//test
 anyVariable = res;
 anyFunction(res);//set any variable or populate another function waiting for the data
}).catch(function (error) {
 console.log(error);
});

For proper error handling.

I hope this helps anyone having these issues. And yes I am aware this technically is not a direct answer to the question but given the answers supplied already I felt the need to provide this alternative solution which dramatically simplified my code on the client and server sides.

Andrew
  • 399
  • 6
  • 15
0

I have changed previous response a little and this solution have been working for me.

function searchlipcutforbrace(cs,id_pff,wt,ofl){
    var params = {
       "cs"  : cs,
       "id"  : id_pff,
       "wt"  : wt,
       "ofl"  : ofl
       }
       
var response = $.ajax({
                    data:  params,
                    url:   'ajax/searchlipcutforbrace.php',
                    async: false,
                    dataType: 'json',
                    success: function (json) {
                        response = json;
                    },
                    type:  'post'
                });    
    return response.responseJSON;
}
Orlando Reyes
  • 93
  • 1
  • 3
-1

I solved it by doing like that:

var return_first = (function () {
        var tmp = $.ajax({
            'type': "POST",
            'dataType': 'html',
            'url': "ajax.php?first",
            'data': { 'request': "", 'target': arrange_url, 'method': 
                    method_target },
            'success': function (data) {
                tmp = data;
            }
        }).done(function(data){
                return data;
        });
      return tmp;
    });
  • Be careful 'async':fale javascript will be asynchronous.
Borin --help
  • 146
  • 2
  • 6
  • @AshishSharma here is working to me : function get_all_company(url){ var result = $.ajax({ type:'GET', url:url, success:function(data){ }, error:function(data){ console.log("error get all comp",data) } }).done(function(data){ // console.log(data.responseJSON) return data; }); return result; }; // maybe my above error bwt dataType:"html" and data:"json format". probably need to match bwt dataType and data in ajax function. – Borin --help May 18 '20 at 02:17
-2

'async': false says it's depreciated. I did notice if I run console.log('test1'); on ajax success, then console.log('test2'); in normal js after the ajax function, test2 prints before test1 so the issue is an ajax call has a small delay, but doesn't stop the rest of the function to get results. The variable simply, was not set "yet", so you need to delay the next function.

function runPHP(){
    var input = document.getElementById("input1");
    var result = 'failed to run php';

    $.ajax({ url: '/test.php',
        type: 'POST',
        data: {action: 'test'},
        success: function(data) {
            result = data;
        }
    });

    setTimeout(function(){
        console.log(result);
    }, 1000);
}

on test.php (incase you need to test this function)

function test(){
    print 'ran php';
}

if(isset($_POST['action']) && !empty($_POST['action'])) {
    $action = htmlentities($_POST['action']);
    switch($action) {
        case 'test' : test();break;
    }
}
SwiftNinjaPro
  • 787
  • 8
  • 17