Skip to content

Instantly share code, notes, and snippets.

@Millsky
Last active January 11, 2019 15:13
Show Gist options
  • Save Millsky/46a62d11f66f1c130e909321d5842a42 to your computer and use it in GitHub Desktop.
Save Millsky/46a62d11f66f1c130e909321d5842a42 to your computer and use it in GitHub Desktop.
Clean Functional Service -> Transform -> Dispatch, with handling for cancellation, failure and success
import R from 'ramda';
import { task, of } from 'folktale/concurrency/task';
import hash from 'object-hash';
function processService(p) {
return p.data;
}
const getDataFailure = data => ({
type: 'FAILURE_TYPE',
data,
});
const getDataCancelled = data => ({
type: 'CANCEL_ME',
data,
});
const getDataSuccess = data => ({
type: 'SOME_TYPE',
data,
});
/* Just a helper function to make our code smaller */
const asChainedTask = R.compose(
// Chain after converting to task
R.chain,
// Curry an unknown number of args
R.o(of),
);
/* Equiv to: /x -> of(x) */
/* R.o - just compresses a lambda via currying */
const asTask = R.o(of);
// F :: _ -> dispatch({t, d})
export const servicePipeline = R.pipe(
// Generate a new task around a service
() => task((resolver) => {
// Just resolve to 1 for now
resolver.reject({ data: 1 });
}),
// Unwrap the data and send it to process service
// Return a new Task within a chain
// Chain always must expose chain
// so chain passed via any morphism will return chain.
// Equiv to: R.chain(/x => of(fn(x)));
asChainedTask(processService),
// Pick up the data and dispatch an action to redux
// Pattern match for each case
R.chain(data => of(data).willMatchWith(R.map(asTask, {
// Chain will return a chain so only need a task
Cancelled: getDataCancelled,
Resolved: getDataSuccess,
Rejected: getDataFailure,
}))),
);
/* */
export default R.memoizeWith(hash, renderPipeline);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment