Skip to content

Instantly share code, notes, and snippets.

@OlivierJM
Created May 25, 2025 07:34
Show Gist options
  • Save OlivierJM/ecdc5f25ee9ca77c427a7cd86b6afb38 to your computer and use it in GitHub Desktop.
Save OlivierJM/ecdc5f25ee9ca77c427a7cd86b6afb38 to your computer and use it in GitHub Desktop.
Fetch data from google spreadsheet or any url, this will return existing data if user is offline and when back online new data will be fetched
import {useState, useEffect} from 'react';
import Papa from 'papaparse';
import {DataItemType} from "@/types.ts";
export const useDataFromSpreadsheet = <T>(sheetUrl: string, transformData: (item: DataItemType) => T) => {
const [data, setData] = useState<T[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<{ message: string } | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
if (!navigator.onLine) {
const cachedData = localStorage.getItem("housingData");
if (cachedData) {
setData(JSON.parse(cachedData));
setLoading(false);
return;
} else {
throw new Error("No internet connection and no cached data available");
}
}
const response = await fetch(sheetUrl);
if (!response.ok) {
throw new Error("Failed to fetch data from Google Sheets");
}
const csvData = await response.text();
Papa.parse(csvData, {
header: true,
complete: (results) => {
const parsedData: T[] = results.data.map((item) => transformData(item as DataItemType));
setData(parsedData);
localStorage.setItem("housingData", JSON.stringify(parsedData));
setLoading(false);
},
error: (err: any) => {
setError({ message: err.message });
setLoading(false);
},
});
} catch (err: any) {
const errorMessage = err.message || "An unknown error occurred";
setError({ message: errorMessage });
// Try to use cached data if available when an error occurs
const cachedData = localStorage.getItem("housingData");
if (cachedData) {
setData(JSON.parse(cachedData));
}
setLoading(false);
}
};
fetchData();
const handleOnlineStatusChange = () => {
if (navigator.onLine) {
// Refetch the data when the app comes back online
fetchData();
}
};
window.addEventListener("online", handleOnlineStatusChange);
window.addEventListener("offline", handleOnlineStatusChange);
return () => {
window.removeEventListener("online", handleOnlineStatusChange);
window.removeEventListener("offline", handleOnlineStatusChange);
};
}, []);
return { data, loading, error };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment