0

I've got an AJAX page that returns some data from a GET. All good. I'm trying to call it from Javascript in response to a user changing the value of a select element called ProductCode. I've come from the C# world if some of my terminology is a little off.

Javascript:

function ProductCodeChange()
{               
    try
    {
        elProductCode = document.getElementById("ProductCode");
        ProductCode = elProductCode.value;
        
        var AJAX_MAGICTOKEN = "773d8626-6b78-4055-bf8b-4fbbaa725550";
        url = "AJAX_GetData.php?";
        url += "MagicToken=" + AJAX_MAGICTOKEN + "&";
        url += "Query=GetProduct&";
        url += "ProductCode=" + ProductCode;
        
        httpxml = new XMLHttpRequest();
        httpxml.onreadystatechange = PopulateProductCode(httpxml);
        alert(">httpxml.open");
        httpxml.open("GET", url, true);
        httpxml.send(null);
    }
    catch (e)
    {
        alert(e.message);
    }
}


function PopulateProductCode(httpxml)
{
    try
    {
        alert(">ProductCodePopulate");
        if (httpxml.readyState == 4 && httpxml.status == 200) 
        {
            data = httpxml.responseText;
            alert(data);
        }
        else
        {
            alert("readyState: " + httpxml.readyState.toString());
            alert("status: " + httpxml.status.toString());
        }
    }
    catch (e)
    {
        alert(e.message);
    }
}

HTML:

<select id="ProductCode" name="ProductCode" onchange="ProductCodeChange();">
<option value="AP1A" >Annual Licence</option>
<option value="AP1M" >Monthly Licence</option>
</select>

I've configured the XMLHttpRequest object to call PopulateProductCode when the onreadystatechange event is fired. I've got quite a lot of work to do with the data returned, and would prefer to have a separate function called when the XMLHttpRequest returns data.

If my C# world, the line httpxml.onreadystatechange = PopulateProductCode(httpxml); sets up the httpxml object with a delegate to call once its ready state has changed. However, when executing the code above, the order of events is:

alert(">ProductCodePopulate");
alert(">httpxml.open");

so my delegate is being called before the GET request is sent.

Am I completely misunderstanding how this object works? How can I achieve what I'd like to do (i.e. keep the functionality in a separate function)?

If you could stick to vanilla Javascript in your answer, that'd be great. I'm not familiar with JQuery yet. Thanks.


Edit: An alternative is:

httpxml.onreadystatechange =
function()
{
    if (this.readyState == 4 && this.status == 200) 
    {
       data = httpxml.responseText;
       alert(data);
       
    }
}

This does work correctly and doesn't get executed until data is returned. From @James answer below, the first version gets executed immediately, but the version immediately above doesn't. I don't understand what is the difference between the two, except that the second doesn't have a function name. Surely they are the same thing, but one version is nameless? Why the difference in processing?

Mark Roworth
  • 409
  • 2
  • 15

2 Answers2

0

In Javascript, this line httpxml.onreadystatechange = PopulateProductCode(httpxml) first calls PopulateProductCode with the httpxml parameter, and assigns the return value of that as the event handler to use when ready state changes.

Simplest is to wrap your call to PopulateProductCode in an anonymous function.

httpxml.onreadystatechange = () => PopulateProductCode(httpxml);
James
  • 20,957
  • 5
  • 26
  • 41
  • Thanks @James. I don't really understand why it does this. I've added a modification able that *does* work correctly, but I don't understand the distinction between my original code and the modified version in terms of how it is handled. Would it be possible to explain. Thanks. – Mark Roworth Sep 14 '21 at 17:10
0

I would recommend changing the approach to a newer implementation. The fetch API. It returns a promise. Improves code readability and is a better approach now days.

Suggested reading:

Fetch API vs XMLHttpRequest

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API