Last active
June 10, 2020 15:32
-
-
Save miteshmap/25f03b7943da9824625a072fd4cd173c to your computer and use it in GitHub Desktop.
React Fetcher with cache for axios request, based on a talk of Dan Abramov: https://youtu.be/nLF0n9SACd4?t=877
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
import CacheSearch from "./CacheSearch"; | |
let tempCacheObjects = {}; | |
/** | |
* Helper function to initiate only single object | |
* for any given promise function name. | |
*/ | |
export const createCacheObject = func => { | |
if (typeof tempCacheObjects[func.name] === "undefined") { | |
tempCacheObjects[func.name] = new CacheSearch(); | |
} | |
return tempCacheObjects[func.name]; | |
}; |
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
/** | |
* Cache class for search. | |
* | |
* Avoid unnecessary api request by caching the results. | |
*/ | |
class CacheSearch { | |
constructor() { | |
this.query = ''; | |
this.queryCount = 0; | |
this.cache = {}; | |
this.cacheHits = 0; | |
this.cacheHitsHistory = []; | |
} | |
getResults(query) { | |
this.query = JSON.stringify(query); | |
if (this.cache[this.query]) { | |
this.cacheHits = this.cacheHits + 1; | |
this.queryCount = this.queryCount + 1; | |
this.cacheHitsHistory.concat(this.query); | |
return this.cache[this.query]; | |
} | |
return null; | |
} | |
cacheResult(results) { | |
this.cache[this.query] = results; | |
this.queryCount = this.queryCount + 1; | |
return results; | |
} | |
} | |
export default CacheSearch; |
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
import { createCacheObject } from "./cache-objects"; | |
/** | |
* Helper function to handle api request for GET method for now. | |
* | |
* Created helper method to avoid error handling everytime we make | |
* api requests. This general function will always be used to make | |
* api request, and it handles caching, returns error correctly so | |
* on usage does not have to do comoplicated condition check and | |
* returns data in promise. | |
* | |
* @param {*} promiseFunc | |
* Promise function name. | |
*/ | |
export const createFetcher = promiseFunc => { | |
return { | |
read: arg => { | |
// Initiate cache and cache responses of stores to avoid | |
// Duplicate api calls. | |
let cachedObj = createCacheObject(promiseFunc); | |
let cachedResults = cachedObj.getResults(arg); | |
if (!cachedResults) { | |
try { | |
return promiseFunc(arg).then( | |
response => { | |
if (!response) { | |
return { error: "error!" }; | |
} | |
if (typeof response.data !== "object") { | |
return { error: "error!" }; | |
} | |
if (!response.data.error && response.data.error) { | |
console.error(cart_result.error_message); | |
return { error: "error!" }; | |
} | |
cachedObj.cacheResult(response.data); | |
return response.data; | |
}, | |
reject => { | |
return { error: reject }; | |
} | |
); | |
} catch (error) { | |
return new Promise(resolve => resolve({ error: error })); | |
} | |
} | |
// read: should always return promise, so that we don't have to | |
// check at api call point if it's a promise or not. | |
return new Promise(resolve => resolve(cachedResults)); | |
} | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
USAGE: