Derick Chooty Derick Chooty - 6 months ago 13
Ajax Question

function call inside another function with using javascript Global variable

Following java script is not working global variable pls help to do. Ajax is working properly and in add_article() function also working as variable but the variable not working undefined.

<script type="text/javascript">
var karat = 0;
function get_advance_amount(element)
{
if (element!="")
{
if (window.XMLHttpRequest)
{
key = new XMLHttpRequest();
key.onreadystatechange = function(){
if (key.status==200 && key.readyState ==4)
{
karat = key.responseText;
//alert(karat); // this is working
}

};
key.open("GET","get_advance_amount.php?q="+element,true);
key.send();
}
}
}
function add_article()
{
get_advance_amount('2');
alert(karat); // this is not working
}
</script>
<button onclick="add_article()">Click me</button>

Answer

The add_article function runs before the XHR's done.

Sample rewrite:

'use strict'

function getAdvanceAmount (element, callback) {
  if (element === '' || !window.XMLHttpRequest) return

  var xhr = new XMLHttpRequest()
  xhr.onreadystatechange = function () {
    if (xhr.status === 200 && xhr.readyState === 4) {
      callback(xhr.responseText)
    }
  }
  xhr.open('GET', 'get_advance_amount.php?q=' + element, true)
  xhr.send()
}

function addArticle () {
  getAdvanceAmount('2', function (karat) {
    console.log(karat)
  })
}

This technique is used as callbacks, where you supply a function that gets called and provided with data once the async operation's done. Here, getAdvanceAmount() accepts a callback which will be run once the XHR's completed. addArticle() could also take a callback if it's necessary to know when it's done.

Newer ways to do this are promises and the proposal for async/await (which actually uses promises behind the scenes). For example, promises would be used like this:

function addArticle () {
  getAdvanceAmount('2').then(karat => console.log(karat))
}

and async/await like this:

async function addArticle () {
  const karat = await getAdvanceAmount('2')
  console.log(karat)
}

However, use of these in a browser environment requires polyfilling and transpiling.