Last active
September 6, 2020 12:24
-
-
Save marceliwac/0141d7c13650747c9e1ca8ab6625331c to your computer and use it in GitHub Desktop.
Temporarily-fixed useLatestData that uses useEffect hook to detect change in 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){ | |
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 {isConnected} = React.useContext(ConnectionContext); | |
const queryString = getQueryStringFromOptions(options); | |
const path = getPathFromOptions(options); | |
const [currentChecksum, setCurrentChecksum] = React.useState(null); | |
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(() => { | |
setData(null); | |
setCurrentChecksum(null); | |
}, [options.path, options.checksumPath]); | |
React.useEffect(() => { | |
async function update() { | |
if(isConnected) { | |
if(data === null ){ | |
setData(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