Created
August 12, 2016 16:38
-
-
Save ezekielchentnik/670e27fdd400da46dd93be0608e53ef1 to your computer and use it in GitHub Desktop.
Session Storage interval caching with fetch and redux
This file contains 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
const OPTIONS = { | |
credentials: 'include', | |
headers: { | |
'Accept': 'application/json', // eslint-disable-line | |
'Content-Type': 'application/json', | |
'X-Requested-With': 'XMLHttpRequest' | |
} | |
}; | |
export function parseResponse(response) { | |
return response.json().then((json) => ({ json, response })); // provide parsed response and original response | |
} | |
export function checkStatus({ json, response }) { | |
if (!response.ok) { // status in the range 200-299 or not | |
return Promise.reject(new Error(response.statusText || 'Status not OK')); // reject & let catch decide how to handle/throw | |
} | |
return { json, response }; | |
} | |
export function normalizeJSON({ json }) { | |
return json; | |
} | |
function hasStorage() { | |
const test = 'test'; | |
try { | |
localStorage.setItem(test, test); | |
localStorage.removeItem(test); | |
return true; | |
} catch(e) { | |
return false; | |
} | |
} | |
function storeJSON(url, json) { | |
sessionStorage.setItem(url, JSON.stringify(json)); | |
return json; | |
} | |
function getNearestTimestamp(interval){ // we round down to nearest interval | |
const coeff = 1000 * 60 * (interval || 5); | |
let date = new Date(); | |
let rounded = new Date(Math.floor(date.getTime() / coeff) * coeff); | |
return rounded.getTime(); | |
} | |
function defaultFetch(url, options){ | |
return fetch(url, options || OPTIONS) | |
.then(parseResponse) | |
.then(checkStatus) | |
.then(normalizeJSON); | |
} | |
function makeFetch(url, options) { | |
if(hasStorage()){ | |
const interval = 5; // use interval for cache key, expire every 5 mins | |
const stamp = getNearestTimestamp(interval); | |
const key = `${url}?_=${stamp}`; | |
const json = JSON.parse(sessionStorage.getItem(key)); | |
if(json){ | |
console.log(`[sessionStorage] ${key}`); | |
return Promise.resolve(json); | |
} | |
return defaultFetch(url, options) | |
.then((json) => storeJSON(key, json)); | |
} | |
return defaultFetch(url, options); | |
} | |
function startAction(type) { | |
return { type }; | |
} | |
function successAction(type, json) { | |
return { type, payload: json, meta: { receivedAt: Date.now() } }; | |
} | |
function failureAction(type, error) { | |
return { type, payload: error, error: true, meta: { receivedAt: Date.now() } }; | |
} | |
export const MY_DATA_REQUEST = 'MY_DATA_REQUEST'; | |
export const MY_DATA_SUCCESS = 'MY_DATA_SUCCESS'; | |
export const MY_DATA_FAILURE = 'MY_DATA_FAILURE'; | |
export function fetchMyData() { | |
return (dispatch) => { | |
dispatch(startAction(MY_DATA_REQUEST)); | |
return makeFetch(spendingURL) | |
.then((json) => dispatch(successAction(MY_DATA_SUCCESS, json))) | |
.catch((error) => dispatch(failureAction(MY_DATA_FAILURE, error))); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment