2

I have been working with the fetch API and got the data logged to the console successfully from the then() but I am looking for a way to put this data in a global variable that I will use later. I was able to do this with reactjs because of its state management but in vanilla javascript, it is hard to do due to the promise returned

Things I have tried

const res = await fetch('./data.json')
    .then(res => res.json())
    .then(data => data) // when I log from here I get the data but can't assign it to a global variable even tried using `var`

using async/await still no hope.

const fun = async () => {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  return response.json()
}
Charles Kasasira
  • 240
  • 1
  • 5
  • 15
  • 2
    If you don't mind me asking, why do you want it in a global variable? Could you consider using a callback where the data is passed as an argument so it can be used by that function or other functions called by that function? – Malekai May 26 '22 at 08:58
  • On second thought, you could avoid multiple callbacks with arguments and polluting the global namespace by using an IIFE with a `data` variable at the first level of its scope ([like this](https://stackoverflow.com/a/72389401/10415695)). – Malekai May 26 '22 at 09:27
  • https://dev.to/chovy/state-management-into-its-own-module-in-vanilla-javascript-58mf – chovy Jun 09 '23 at 06:59

2 Answers2

2

Inside an asynchronous function getData which fetches the remote data, you can get the parsed JSON body as a JavaScript object and assign it to a variable dataGlobal defined in the global context.

Of course, you have to wait for getData to execute before dataGlobal is declared. Therefor, I'm using an asynchronous IIFE.

let dataGlobal;

const getData = async () => {
  const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
  const data = await response.json();
  dataGlobal = data;
  return data;
};

(async () => {
  await getData();
  console.log(dataGlobal);
})();
alexanderdavide
  • 1,487
  • 3
  • 14
  • 22
  • Thanks, @alexanderdavide this is helpful though I wanted to map through this array outside of any kind of function otherwise this seems like mapping it inside the `then()`. I Was wondering if there is a way to access it in the global scope. once again thank you. – Charles Kasasira May 26 '22 at 09:15
  • You're welcome. I must say that I fail to understand what your exact goal is and why you would want to do it. If you would provide more information, I could maybe help more. – alexanderdavide May 26 '22 at 09:30
  • There was no exact goal. I was practicing and decided to do this using the fetch API (no libraries) to pick up a JSON file and map through it while creating some sort of chart. After a while, I realized that I was only logging the data to the console but had never stored it in a global variable before. When I failed to find a solution, I decided to come here. But I got to work on it. – Charles Kasasira May 26 '22 at 09:40
1

While I understand that you'd like a global variable for your data, I would advise against polluting the global namespace (see also: [1], [2], [3] and [4]).

You could instead encapsulate everything in an Immediately Invoked Function Expression (IIFE), and have your fetch method inside of it with all of the code related to that area of your program.

Then, by rearranging @alexanderdavide's answer, we get the following code:

(async () => {
  let data_local;

  const getData = async () => {
    const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const data = await response.json();
    dataGlobal = data;
    return data;
  };

  await getData();
  console.log(data_local);

  // your code goes here...
})();

You could also use the following alternative as well:

(async () => {
  const getData = async () => {
    const response = await fetch("https://jsonplaceholder.typicode.com/todos/1");
    const data = await response.json();
    dataGlobal = data;
    return data;
  };

  let data_local = await getData();
  console.log(data_local);


  // your code goes here...
})();

That way your data_local variable would be available to everything beneath it but not outside of the IIFE itself, protecting the global namespace while allowing multiple methods access to the same variable without using callbacks with a data argument.

NOTE: please be careful if/when you change the data variable, you might end up changing it multiple times and inadvertently causing an error because of missing / improperly formatted data.

Good luck.

Malekai
  • 4,765
  • 5
  • 25
  • 60