Adnan
Adnan

Reputation: 98

How to use local storage to store data from an API

I want to get data from an API only once in a while(say, once every hour) and store it locally and use that data on my website without having to call that api again and again everytime the person refreshes the browser. How can we achieve this. Can we use localStorage for that purpose. If yes then how?

I am using this:

fetch("https://coronavirus-tracker-api.herokuapp.com/deaths")
.then(res=>{
  return res.json();
})
.then(data=>{
  localStorage.setItem("data",JSON.stringify(data));
  console.log(localStorage.getItem("data"))
})

but this would call the api everytime the page reloads. But instead of calling to the api again and again I want to store data in the localstorage and get data to view on the page from there.

Upvotes: 1

Views: 3371

Answers (1)

JStw
JStw

Reputation: 1205

It depends actually on which quantity of data you want to store. Generally you prefers to use the localStorage when you need to deals with small amount of data.

Another alternative is also possible, it's the IndexedDB which is more compliant and allow you to store more data.

You can find the API here: https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API You can follow also some tutorials about IndexedDB to see actually how it works.

Finally, you can find the localStorage vs. IndexedDB usage response here: https://softwareengineering.stackexchange.com/questions/219953/how-is-localstorage-different-from-indexeddb

But if you want to steal use the localStorage, then you can check before fetching your data if the key storage "data" is used :

const data = localStorage.getItem('data');

if (!data) {
 // then fetch your data
}

Be careful, the localStorage always store Key Value pairs, and the value will always be a string. So if you want to deals with your value when you retrieved it, do not forget to JSON.parse(data)

Edit: Refresh data outdated when re-opening tab

To update your data every 3-4 hours, you can store the date when you fetched the data. You need to update a little but the treatment of your response in the promise results :

const getDataFromLocalStorage = () => {
  const dataStringified = localStorage.getItem('data');
  return data && JSON.parse(dataStringified) || null;
};

const areDataOutdated = (receivedAt) => {
    if (!dataReceivedAt || isNaN(Date.parse(receivedAt)) {
       return true;
    }
    // Basically, we take the actual date, and we removed 4 hours
    const checkDate = new Date(new Date().getTime() - (60 * 60 * 4 * 1000));
    // If the data received is lower than the checkDate, it means that data are outdated.
    return new Date(receivedAt).getTime() < checkDate.getTime();
};

const data = getDataFromLocalStorage();
if (!data || areDataOutdated(data && data.receivedAt)) {
   // then fetch your data
   fetch("https://coronavirus-tracker-api.herokuapp.com/deaths")
     .then(res=> {
       // instead of storing directly your response, construct a object that will store also the date
       localStorage.setItem("data", JSON.stringify({response: res.json(), receivedAt: new Date()}));
       console.log(localStorage.getItem("data"))
     })
}

Edit 2: Refresh the data while staying on page

const getDataFromLocalStorage = () => {
  const dataStringified = localStorage.getItem('data');
  return data && JSON.parse(dataStringified) || null;
};

const fetchData = () => {
  fetch("https://coronavirus-tracker-api.herokuapp.com/deaths")
     .then(res=> {
       // instead of storing directly your response, construct a object that will store also the date
       localStorage.setItem("data", JSON.stringify({response: res.json(), receivedAt: new Date()}));
       console.log(localStorage.getItem("data"))
     })
}

setInterval(() => {
   fetchData();
}, 1000 * 60 * 60 * 4) // every 4 hours, we'll fetch the data.

const data = getDataFromLocalStorage();
if (!data) {
   fetchData();
}

But you can combine also with the outdated data check from Edit 1.

Upvotes: 3

Related Questions