-1

I'm trying to get a variable but it's returning undefined. Maybe I'm having an issue with scope or timing?

var pid = getPart(upc);
console.log('pid: '+pid);

addPart(pid);

getPart() is not returning a value but the post is working and getting id. I just can't log pid or use it in addPart() because it seems to not be returning.

function getPart(upc){
    $.post('include/_getpart.php', {upc: upc}, function(data){
        name = data.name;
        id = data.id;

        return id;
    }, "json");
}

For completeness, I will post my entire script.

<script language="javascript">
var success = 0;
var addedArray = [];

function add(form) {
    console.log('form for '+form.name);
    $(':input[type="number"]', form).each(function() {
        if (this.value > 0){
            upc = this.name;
            qty = this.value;
            console.log(upc + ': ' + qty);

            var pid = getPart(upc);
            console.log('pid: '+pid);

            //addPart(pid);
        }
    });
    if (success==1) {
        console.log(addedArray);
    }
}

function getPart(upc){
    $.post('include/_getpart.php', {upc: upc}, function(data){
        name = data.name;
        id = data.id;
        /*
        console.log('name: '+name);
        console.log('product id: '+pid);

        var productArray = new Array(name, qty);
        console.log(productArray);
        addedArray.push(productArray);
        */
        return id;
    }, "json");
}

function addPart(pid){
    if (!pid) {
        console.log('error: product id (pid) was not found');
        return;

    } else {
        $.post('include/_addpart.php', {pid: pid, qty: qty}, function(data) {
            console.log('_addpart.php response: '+data);
        });
    }
}

</script>

All the ajax requests work, I'm wondering if the bit of lag the may make while communicating with the server warrants the setting of said variable to be skipped. If so, should I put a timeout in there, and how.

Ryan Lutz
  • 247
  • 1
  • 12
  • possible duplicate of [Variable doesn't get returned from AJAX function](http://stackoverflow.com/questions/12475269/variable-doesnt-get-returned-from-ajax-function) – Denys Séguret Sep 13 '13 at 19:30
  • possible duplicate of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – Jason P Sep 13 '13 at 19:35

1 Answers1

2

This is caused by the asynchronous nature of AJAX and the fact that you can't return from a callback. The sequence of events is this:

  • You request the part (getPart()) by using an AJAX call.
  • Within the AJAX call (post) you provide an anonymous function that us supposed to be called when the AJAX call is done.
  • Because it is an asynchronous call, the JS continues executing, i.e. JS continues to the line after your getPart call, which is console.log('pid: '+pid);
  • JS will output pid: undefined because the var pid has been declared but not defined in the line before.
  • JS will continue whatever is next until the response from the AJAX call comes back.
  • When the response comes back, it will execute the anonymous function from earlier.
  • At the end of that function, it sees return id;, however, there is nothing waiting for this return any more.

You will have to do something like this:

function add(form) {
    console.log('form for '+form.name);
    $(':input[type="number"]', form).each(function() {
        if (this.value > 0){
            ...
            getPart(upc, function(pid){
                // THIS ANONYMOUS FUNCTION WILL BE EXECUTED ONCE THE AJAX CALL RETURNS
                console.log('pid: '+pid);
                //addPart(pid);
            });    
        }
    });
    ...
}

function getPart(upc, callback){
    $.post('include/_getpart.php', {upc: upc}, function(data){
        name = data.name;
        id = data.id;
        // CALLBACK IS THE ANONYMOUS FUNCTION YOU DECLARED ABOVE
        callback(id);
    }, "json");
}

EDIT:

If all you want to do is call addPart (and not also do the console.log), you don't need the anonymous function... then you can do this:

function add(form) {
    console.log('form for '+form.name);
    $(':input[type="number"]', form).each(function() {
        if (this.value > 0){
            ...
            getPart(upc, addPart);    
        }
    });
    ...
}

function getPart(upc, callback){
    $.post('include/_getpart.php', {upc: upc}, function(data){
        name = data.name;
        id = data.id;
        callback(id);
    }, "json");
}
Steve
  • 8,609
  • 6
  • 40
  • 54