Search code examples
javascriptjsongetxmlhttprequest

My function will log JSON data from an XMLHttpRequest but won't return it?


I'm trying to access the NHL API for a personal project. I was getting CORS request errors and found the below solution to access all the different sites (some worked prior, and some didn't).

I'm passing through a link and based one the outputs it seems to be accessing the data on the page and displaying it in both JSON and string format. The only problem is I can't return any of that data out of the function as an object or otherwise.

Last 2 logs show undefined, and the 2 within the function output the data I want. Am I missing something obvious or is there a deeper issue with the website access?

Thanks.

function getJSON(url){
    let request = new XMLHttpRequest();
    request.open('GET', url);
    request.onload = function () {
  // Begin accessing JSON data here
  let data = JSON.parse(this.response);
  if (request.status >= 200 && request.status < 400) {
    //Start writing function here
    console.log(data);
    console.log(JSON.stringify(data));
    
    let data2 = JSON.stringify(data)
    return data2
  } else {
    console.log('error');
  }
}
request.send();
}

let data1 = getJSON("https://statsapi.web.nhl.com/api/v1/people/8476459/stats?stats=statsSingleSeason&season=20212022")
console.log(data1);
console.log(JSON.stringify(data1));

Solution

  • You are doing asynchronous call, which means you return the value before the response even come back, that's why data1 is undefined

    You can see this post for more information.

    For your case, you can wrap the request with Promise

    async function getJSON(url) {
      return new Promise(function (resolve, reject) {
        let request = new XMLHttpRequest();
        request.open('GET', url);
        request.onload = function () {
          // Begin accessing JSON data here
          let data = JSON.parse(this.response);
          if (request.status >= 200 && request.status < 400) {
            //Start writing function here
           
            let data2 = JSON.stringify(data)
            return resolve(data);
          } else {
            return reject('error')
          }
        }
        request.send();
      }
      )
    }
    
    async function main() {
      let data1 = await getJSON("https://statsapi.web.nhl.com/api/v1/people/8476459/stats?stats=statsSingleSeason&season=20212022")
    console.log(data1);
    console.log(JSON.stringify(data1)); 
    }
    
    main();

    A better way is to use Fetch API

    async function getJSON(url) {
      const data1 = await fetch(url).
        then(response => response.json());
      return data1;
    }
     
    async function main() {
      const result = await getJSON('https://statsapi.web.nhl.com/api/v1/people/8476459/stats?stats=statsSingleSeason&season=20212022');
      console.log(result);
    }
    
    main();