Created
September 2, 2020 16:20
-
-
Save marceliwac/cfa0705de7db0bb44901fcf48430720c to your computer and use it in GitHub Desktop.
The useLatestData hook with a bug that does not take into account updated path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import {api} from '../data/store.js'; | |
import config from "../config/config"; | |
import ConnectionContext from "../contexts/ConnectionContext"; | |
const Logger = require('@marceliwac/logger'); | |
const refreshInterval = (1000 * config.dataRefreshIntervalInSeconds) || 10000; | |
async function newDataAvailable(checksumPath, currentChecksum){ | |
Logger.debug('Checking if new data is available.'); | |
try { | |
const response = await api(checksumPath); | |
if (response.status === 200) { | |
return response.data.checksum; | |
} | |
} catch(error) { | |
Logger.error('Could not fetch the latest checksum!', error); | |
throw error; | |
} | |
} | |
async function fetchData(endpoint) { | |
Logger.debug('Fetching latest data.'); | |
try { | |
const pre = Date.now(); | |
const response = await api(endpoint); | |
const post = Date.now(); | |
Logger.debug('Fetching took: ' + (post-pre)/1000 + ' seconds.'); | |
Logger.debug('Data fetched:', response.data); | |
if (response.status === 200) { | |
return response.data; | |
} | |
Logger.error('Could not retrieve data! API response code was not 200.'); | |
} catch(error) { | |
Logger.error('Could not fetch the latest data!', error); | |
throw error; | |
} | |
} | |
function getQueryStringFromOptions(options) { | |
let queryString = ''; | |
if(options | |
&& Object.prototype.hasOwnProperty.call(options, 'parameters') | |
&& Array.isArray(options.parameters) | |
&& options.parameters.length >= 1) { | |
queryString += '?'; | |
options.parameters.forEach((parameter, index) => { | |
queryString += `parameters[]=${parameter}`; | |
if(index + 1 < options.parameters.length){ | |
queryString += '&'; | |
} | |
}); | |
} | |
return queryString; | |
} | |
function getPathFromOptions(options) { | |
if(options | |
&& Object.prototype.hasOwnProperty.call(options, 'path')){ | |
return options.path; | |
} | |
return '/'; | |
} | |
function getChecksumPathFromOptions(options) { | |
if(options | |
&& Object.prototype.hasOwnProperty.call(options, 'checksumPath')){ | |
return options.checksumPath; | |
} | |
return '/'; | |
} | |
export default function useLatestData(options) { | |
const [data, setData] = React.useState(null); | |
const [currentChecksum, setCurrentChecksum] = React.useState(null); | |
const {isConnected} = React.useContext(ConnectionContext); | |
const queryString = getQueryStringFromOptions(options); | |
const path = getPathFromOptions(options); | |
const checksumPath = getChecksumPathFromOptions(options); | |
const refresh = Object.prototype.hasOwnProperty.call(options, 'refresh') ? options.refresh : false; | |
Logger.debug(`Data will ${(refresh ? '' : 'not ')}be automatically refreshed.`); | |
React.useEffect(() => { | |
async function update() { | |
if(isConnected) { | |
if(data === null){ | |
const fetchedData = await fetchData(`${path}${queryString}`); | |
setData(fetchedData); | |
return; | |
} | |
const newCurrentChecksum = await newDataAvailable(checksumPath, currentChecksum); | |
if (currentChecksum !== newCurrentChecksum) { | |
setCurrentChecksum(newCurrentChecksum); | |
const fetchedData = await fetchData(`${path}${queryString}`); | |
setData(fetchedData); | |
} | |
} | |
} | |
update().catch((error) => { | |
Logger.error('Could not update or fetch the latest the data!', error); | |
}); | |
if(refresh | |
&& options | |
&& Object.prototype.hasOwnProperty.call(options, 'checksumPath')) { | |
const interval = setInterval(update, refreshInterval); | |
return () => clearInterval(interval); | |
} | |
}, [checksumPath, currentChecksum, data, isConnected, options, options.checksumPath, path, queryString, refresh]); | |
return [data]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment