Plan/Plan/react/dashboard/src/hooks/dataFetchHook.js

66 lines
3.1 KiB
JavaScript

import {useEffect, useState} from "react";
import {useNavigation} from "./navigationHook";
import {useDataStore} from "./datastoreHook";
import {useMetadata} from "./metadataHook";
import {staticSite} from "../service/backendConfiguration";
export const useDataRequest = (fetchMethod, parameters) => {
const [data, setData] = useState(undefined);
const [loadingError, setLoadingError] = useState(undefined);
const {updateRequested, finishUpdate} = useNavigation();
const {refreshBarrierMs} = useMetadata();
const datastore = useDataStore();
/*eslint-disable react-hooks/exhaustive-deps */
useEffect(() => {
datastore.setAsUpdating(fetchMethod);
const handleResponse = (json, error, skipOldData, timeout) => {
if (json) {
const timestamp = json.timestamp;
if (!staticSite && timestamp) {
// Data has timestamp, the data may come from cache
const acceptedTimestamp = timestamp + (refreshBarrierMs ? refreshBarrierMs : 15000);
if (acceptedTimestamp < updateRequested) {
// Request again, received data was too old
setTimeout(() => {
fetchMethod(new Date().getTime(), ...parameters)
.then(({data: json, error}) => {
handleResponse(json, error, true, timeout >= 12000 ? timeout : timeout * 2);
});
}, timeout);
} else {
// Received data was new enough to be shown
setData(json);
datastore.storeData(fetchMethod, json);
datastore.finishUpdate(fetchMethod)
finishUpdate(json.timestamp, json.timestamp_f, datastore.isSomethingUpdating());
}
if (!skipOldData) {
// Old data is shown on first pass, further passes skip old data.
setData(json);
datastore.storeData(fetchMethod, json);
finishUpdate(json.timestamp, json.timestamp_f, datastore.isSomethingUpdating());
}
} else {
// Response data is not cached, no timestamp, show it immediately
setData(json);
datastore.finishUpdate(fetchMethod);
finishUpdate(json.timestamp, json.timestamp_f, datastore.isSomethingUpdating());
}
} else if (error) {
console.warn(error);
datastore.finishUpdate(fetchMethod)
setLoadingError(error);
finishUpdate(0, "Error: " + error.message, datastore.isSomethingUpdating());
}
};
fetchMethod(updateRequested, ...parameters).then(({data: json, error}) => {
handleResponse(json, error, false, 1000);
});
}, [fetchMethod, ...parameters, updateRequested, refreshBarrierMs])
/* eslint-enable react-hooks/exhaustive-deps */
return {data, loadingError};
}