7

Value isn't replace and function return 0. How to fix it? (react-native 0.30, IOS 10.0 Simulator)

export function getCategoryList() {
  var xhr = new XMLHttpRequest();
  jsonResponse = null;

  xhr.onreadystatechange = (e) => {
    if (xhr.readyState !== 4) {
      return;
    }

    if (xhr.status === 200) {
      console.log('SUCCESS', xhr.responseText);
      jsonResponse = JSON.parse(xhr.responseText);
    } else {
      console.warn('request_error');
    }
  };

  xhr.open('GET', 'https://httpbin.org/user-agent');
  xhr.send();

  return jsonResponse;
}
kaminarifox
  • 413
  • 1
  • 5
  • 14
  • 1
    The request is asynchronous, which means that the request is sent, your function returns a null value and then some time later the request is completed. Look at passing a callback function into `getCategoryList()` (easy) or promises (a bit more difficult, but not much). – Reinstate Monica Cellio Aug 08 '16 at 12:47
  • 6
    Read: http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call – Ivan Chernykh Aug 08 '16 at 12:47
  • you should look for [promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) – Olivier Boissé Aug 08 '16 at 12:48

2 Answers2

8

You can't return the value like that.

I would suggest going with either callbacks or promises:

Callback:

function getCategoryList(callback) {
  var xhr = new XMLHttpRequest();

  xhr.onreadystatechange = (e) => {
    if (xhr.readyState !== 4) {
      return;
    }

    if (xhr.status === 200) {
      console.log('SUCCESS', xhr.responseText);
      callback(JSON.parse(xhr.responseText));
    } else {
      console.warn('request_error');
    }
  };

  xhr.open('GET', 'https://httpbin.org/user-agent');
  xhr.send();
}

getCategoryList(data => console.log("The data is:", data));

Promises:

function getCategoryList() {
  var xhr = new XMLHttpRequest();

  return new Promise((resolve, reject) => {

    xhr.onreadystatechange = (e) => {
      if (xhr.readyState !== 4) {
        return;
      }

      if (xhr.status === 200) {
        console.log('SUCCESS', xhr.responseText);
        resolve(JSON.parse(xhr.responseText));
      } else {
        console.warn('request_error');
      }
    };

    xhr.open('GET', 'https://httpbin.org/user-agent');
    xhr.send();
  });
}

getCategoryList().then(res => console.log("The result is", res));
Nicholas Robinson
  • 1,359
  • 1
  • 9
  • 20
  • So with AJAX, this means that there is no way to use a simple function call like `getCategoryList()` that will return data? This would be much more convenient. Update: it looks like the closest solution is to use `async` / `await` but then you still cannot call the function directly, you have to call it with the await keyword before the function name (even if you nest the await function call in another function, await is needed to call the other function too): https://stackoverflow.com/questions/48969495/in-javascript-how-do-i-should-i-use-async-await-with-xmlhttprequest/48969580#48969580 – baptx Jan 18 '20 at 19:03
1

You can return the request response if XHR is synchronous (xhr.open('GET', 'https://httpbin.org/user-agent', false)), doing a infinite loop that breaks when the request is finished.

Notes:

  • Synchronous XHR is deprecated;
  • Infinite loop will stop the page while XHR isn't finished (e.g, a game).

function getCategoryList() {

    var xhr = new XMLHttpRequest();
    xhr.open("GET", "https://httpbin.org/user-agent", false);
    xhr.send();

    // stop the engine while xhr isn't done
    for(; xhr.readyState !== 4;)

    if (xhr.status === 200) {

        console.log('SUCCESS', xhr.responseText);

    } else console.warn('request_error');

    return JSON.parse(xhr.responseText);
}
  • 2
    Synchronous http requests are not supported – kaminarifox Aug 08 '16 at 13:57
  • @iwasmusic They're, but deprecated, then they'll be removed in the future. That's what you wanted ("How can I return XMLHttpRequest response from..."). –  Aug 08 '16 at 14:06