22

I'm trying to get JSON saved into a variable, but it seems I don't understand everything here. I get JSON show up in console a once the way I like, but after I try to call it again later it only returns promise. How can I get JSON saved into a variable, so I could use objects in JSON later?

var jsondata = fetch(url).then(
    function(u){ return u.json();}
  ).then(
    function(json){
      console.log(json);
    }
  )
console.log(jsondata);
VLAZ
  • 26,331
  • 9
  • 49
  • 67
J Hightow
  • 233
  • 1
  • 2
  • 4
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Matt Morgan Jan 27 '18 at 12:55

6 Answers6

27

The fetch API is Promise based and will always return a new Promise either resolved or rejected. You have multiple options to return the result.

Async/Await

async function getData(url) {
  const response = await fetch(url);

  return response.json();
}

const data = await getData(url);

console.log({ data })

Callback

function getData(url, cb) {
  fetch(url)
    .then(response => response.json())
    .then(result => cb(result));
}

getData(url, (data) => console.log({ data }))
marcobiedermann
  • 4,317
  • 3
  • 24
  • 37
  • 3
    `.then(result => result)` is pointless. And `const result = await response.json(); return result` is pretty much the same thing. You can simply `return response.json()` – Thomas Jan 27 '18 at 11:46
  • the Async/Await example causes an error with the message "Uncaught SyntaxError: await is only valid in async functions, async generators and modules" – Sharuzzaman Ahmat Raslan Apr 04 '23 at 03:03
  • 1
    @SharuzzamanAhmatRaslan Yes, `await` can only be called in an `async` function. Except in some newer versions of Node.js that support top-level await: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#top_level_await – marcobiedermann Apr 04 '23 at 07:00
10
let jsondata;    
fetch(url).then(
        function(u){ return u.json();}
      ).then(
        function(json){
          jsondata = json;
        }
      )

Basically you need to assign your jsondata variable once the promise resolves with the actual data. Currently, you're assigning the entire promise to your jsondata variable which is not what you want.

bamtheboozle
  • 5,847
  • 2
  • 17
  • 31
  • 1
    technically this is possible, and correct/working code. But I'd highly discourage this approach. Because now you have to implement/duplicate the same state-management that the Promises already provide you just to know when `jsondata` is filled and it is safe to use that value. – Thomas Jan 27 '18 at 11:40
1

You can create a separate function outside the fetch function to deal with json data like in below code the fetch function is passing the complete json object to another function called "data_function" we can proceed and work with JSON object in through this "data_function".

//fetch function
fetch(url).then(
function(u){ return u.json();}
).then(
function(json){
data_function(json); //calling and passing json to another function data_function
}
)

//another functions
function data_function(data){
alert(data.length); 
}
A.Aleem11
  • 1,844
  • 17
  • 12
0

Another option is using a callback as a parameter this way you aren't exposing a variable to global scope.

function getFromAPI(url, callback){
  var obj;
  fetch(url)
    .then(res => res.json())
    .then(data => obj = data)
    .then(() => callback(obj))
 }

getFromAPI('https://jsonplaceholder.typicode.com/posts', getData);

function getData(arrOfObjs){
  var results = "";
  arrOfObjs.forEach( (x) => {
    results += "<p> Id: " + x.id + "<ul>"
    Object.keys(x).forEach( (p) => {
        results += "<li>" + (p + ": " + x[p]) + "</li>";
    });
    results += "</ul> </p> <hr>"
  })
  results += "";
  document.getElementById("myDiv").innerHTML = results;
}

http://jsfiddle.net/5gch2yzw/

Travis
  • 1,674
  • 1
  • 9
  • 14
0

You can create another async function, getData(), in this example, and add the data from the fetched URL to the global variable.

When the getData() function is called, it fetches the city data from the provided URL asynchronously using the fetchData() function. Once the data is successfully fetched, it is added to the global variable citiesData, and you can use this data in other parts of your code.

async function fetchData(url) {
    const response = await fetch(url);
    const data = await response.json();
    return data;
}

const citiesData = [];
const url = 'https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';

// Fetch data only once
async function getData() {
    const data = await fetchData(url);
    citiesData.push(...data);
}

getData();


console.log(citiesData);
Flamingo
  • 322
  • 1
  • 11
-1

Easiest approach is to use async/await method.

Simply copy & paste the following code in your chrome dev console to see the magic:

async function githubUsers() {
            let response = await fetch('https://api.github.com/users')
            let users = await response.json()
            console.log(users)
    }

githubUsers()
Shoaib Khalil
  • 1,874
  • 17
  • 10