0

I've read a few StackOverflow posts, googled it but still can't get what I want.

I simply want to get a JSON from Google's API and import it to a variable so I can filter it the way I want, the following code is what I have so far:

<!DOCTYPE html>
<html>
<body>

Term: <input type="text" id="field1" value="Mc Donalds in New York"><br>

<button onclick="myFunction()">Search</button>

<script>
function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    xhr.open(method, url, true);
    xhr.responseType = 'json';
  } else if (typeof XDomainRequest != "undefined") {
    xhr = new XDomainRequest();
    xhr.open(method, url);
    xhr.responseType = 'json';
  } else {
    xhr = null;
  }
  return xhr;
}

function myFunction() {
    var termo = document.getElementById("field1").value;
    var URL = "https://maps.googleapis.com/maps/api/place/textsearch/json?query="+termo.replace(" ","+")+"&key=HIDDEN_KEY";
    var data = createCORSRequest('GET',URL);
    if (!data) {
      throw new Error('CORS not supported');
    }
}
</script>

</body>
</html>

When I do:

console.log(data);

I get:

enter image description here

When I do:

JSON.parse(data.responseText);

I get:

Uncaught DOMException: Failed to read the 'responseText' property from 'XMLHttpRequest': The value is only accessible if the object's 'responseType' is '' or 'text' (was 'json').

What should I get on console.log: https://pastebin.com/4H7MAMcM

How can I get the JSON from XMLHttpRequest correctly?

Also worth mentioning, I'm using Cross-Origin Resource Sharing (CORS) because I couldn't access the domain from my local IP.

--Edit-- Phil thought this was a matter of not being able to return response from a asynchronous, but its wrong, I've tried using Ajax, XMLHttpRequest and now using CORS, the duplicate notation was incorrect, please remove it.

1 Answers1

-1

This behaviour is documented on MDN;

If responseType is set to anything other than the empty string or "text", accessing responseText will throw InvalidStateError exception.

Instead, you need to use the response property. Since you specified json as the responseType, response will be a JavaScript object (no need to JSON.parse it).

Aside from this, you'll also need to treat the AJAX request as asynchronous, rather than synchronous. For more info on that, see How do I return the response from an asynchronous call?.

Eventually, you should end up with something like;

function createCORSRequest(method, url, cb) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    xhr.open(method, url, true);
    xhr.responseType = 'json';
    xhr.onreadystatechange = function () {
        if (this.readyState === 4) {
        cb(this.response);
      }
    }
    xhr.send(null);
  } else if (typeof XDomainRequest != "undefined") {
    xhr = new XDomainRequest();
    xhr.open(method, url);
    xhr.responseType = 'json';
  } else {
    xhr = null;
  }
  return xhr;
}

createCORSRequest('POST', '/echo/json/', function (response) {
    console.log(response);
});

https://jsfiddle.net/ez3xt6ys/

However, the browser support seems patchy for this at best; https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response. Instead, it is more common to see the responseType being left as text, and for people to JSON.parse() the responseText property.

Matt
  • 74,352
  • 26
  • 153
  • 180