Last active
April 20, 2020 20:40
-
-
Save codfish/b96dd88d051e2c7d651746ce67b09dbf to your computer and use it in GitHub Desktop.
Dynamic RSAA (redux-api-middleware) cache middleware. Must come before rssa in middleware order.
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 { RSAA } from 'redux-api-middleware'; | |
import get from 'lodash/get'; | |
/** | |
* Intercept redux api middleware actions and bailout of api resource requests | |
* if the resource is already in the store. | |
* | |
* NOTE: State always gets updated on non-GET requests, essentially updating our "cache" | |
* | |
* Examples of resource routes that we want to cache: | |
* - /collection | |
* - /collection/<primary-key> | |
* | |
* Note: <primary-key> has to be something with non-alpha characters. guids, eth address, integer, | |
* mongoid's would all work, but it's not a perfect science. Adjust the regex accordingly. | |
* | |
* @see {@link https://github.com/agraboso/redux-api-middleware#bailing-out} | |
*/ | |
export default function cacheMiddleware() { | |
return next => action => { | |
// if action is an api GET request for a resource we already have, prevent the request | |
if (action[RSAA] && action[RSAA].method === 'GET' && !action[RSAA].bailout) { | |
const url = new URL(action[RSAA].endpoint); | |
const pathParts = url.pathname.split('/').slice(1); | |
// if it's not a resource route then just keep moving | |
// NOTE: For "resource" routes, the last item in the url path should be an address | |
// and the second to last item should be the resource name/type. | |
let resource = pathParts[pathParts.length - 2]; | |
let primaryKey = pathParts[pathParts.length - 1]; | |
if (!resource || primaryKey.match(/^[a-zA-Z-_]+$/)) { | |
resource = pathParts[pathParts.length - 1]; | |
primaryKey = null; | |
} | |
// Set the bailout property of the RSAA action object. Should be a function that returns | |
// a boolean. If it's true the request will NOT happen. Function takes redux state as a param. | |
// @see {@link https://github.com/agraboso/redux-api-middleware#bailing-out} | |
// eslint-disable-next-line no-param-reassign | |
action[RSAA].bailout = state => get(state, `entities.${resource}${primaryKey && `.${primaryKey}`}`, false) !== false; | |
} | |
return next(action); | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment