Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Redux resources, untested
/*
Create (cacheable) resources, and endpoints that require some state that you want to hide from the
arguments, like a JWT for authenticating remote calls.
Returns a function that will be accepted by redux-thunk.
*/
/**
* create a redux-resource function
* @param {Function} remote(args, getState)
* @param {Function} local(args, getState)
* @returns {Function} thunk(dispatch, getState)
*/
export function createResource({ remote, local }) {
return (args, handler) => {
return (dispatch, getState) => {
const callHandler = resource => handler(resource, dispatch, getState);
const callFetch = fetcher => fetcher(args, getState);
const localResult = local ? callFetch(local) : undefined;
if (localResult === undefined) {
return callHandler(callFetch(remote));
}
return callHandler(Promise.resolve(localResult));
}
}
}
/**
* simple function to create a remote-only api endpoint
* @param {Function} remote
* @returns {Function} thunk(dispatch, getState)
*/
export function createRemoteResource(remote) {
return createResource({ remote });
}
/*
Usage for some simple endpoints
*/
const getProductById = createResource({
/**
* fetch remote data
* @param {Object} arguments
* @param {Function} getState
* @returns {Promise}
*/
remote ({ productId }, getState) {
return window.fetch(`/product/${productId}`, {
headers: {
Authorization: `bearer ${getState().jwt}`
}
});
},
/**
* get local state, result wil get wrapped in a Promise.resolve.
* if it returns undefined, the remote data will be fetched.
* @param {Object} arguments
* @param {Function} getState
* @returns {*}
*/
local ({ productId }, getState) {
return getState().products[productId];
}
});
const getUserById = createRemoteResource(({ userId }) => {
return window.fetch(`/user/${userId}`);
});
/*
implementation in a Redux action
*/
function fetchUser(userId) {
return getUserById({ userId }, (resource, dispatch) => {
dispatch({ type: 'FETCH_USER' });
return resource
.then(user => dispatch(fetchUserSuccess(user)))
.catch(error => dispatch(fetchUserFailed(error)))
});
}
function fetchUserSuccess(user) {
return {
type: 'FETCH_USER_SUCCESS',
payload: { user }
};
}
function fetchUserFailed(error) {
return {
type: 'FETCH_USER_FAILED',
payload: { error }
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.