Last active
January 19, 2022 22:23
-
-
Save simontegg/932bcc27ddddce73bb815ef6df16e9f5 to your computer and use it in GitHub Desktop.
Handling nullability in selectors
This file contains hidden or 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 { createSelector } from 'reselect' | |
| export const getWorkflows = context => context.workflows | |
| export const getId = context => context.activeId | |
| /** OPTION 1 */ | |
| /** | |
| * Will probably throw an error | |
| * @returns {?object} | |
| */ | |
| export const getTheWorkflow = createSelector( | |
| getWorkflows, | |
| getId | |
| // id null ? | |
| (workflows, id) => workflows.find(workflow => workflow.id === id ) | |
| ) | |
| /** | |
| * Will probably throw an error 'cannot read propery "name" of undefined' | |
| * @returns {?string} | |
| */ | |
| export const getTheWorkflowName = createSelector( | |
| getTheWorkflow, | |
| // workflow undefined ? | |
| workflow => workflow.name | |
| ) | |
| /** OPTION 2 */ | |
| /** | |
| * Lots of null/undefined tests. But still unclear if it | |
| * @returns {?object} or | |
| * @returns {object} | |
| */ | |
| export getTheWorkflow = createSelector( | |
| getWorkflows, | |
| getId, | |
| (workflows, id) => id ? workflows.find(workflow => workflow.id === id ) : {} | |
| ) | |
| /** | |
| * Safer but getTheWorkflow could still be undefined | |
| * @returns {string} | |
| */ | |
| export const getTheWorkflowName = createSelector( | |
| getTheWorkflow, | |
| // workflow undefined from getTheWorkflow ? | |
| workflow => workflow ? workflow.name : '' | |
| ) | |
| /** OPTION 3 */ | |
| // Equalvalent to above, but we don't care if id === undefine | |
| export getTheWorkflow = createSelector( | |
| getWorkflows, | |
| getId, | |
| (workflows, id) => workflows.find(workflow => workflow.id === id) | |
| ) | |
| export const getTheWorkflowName = createSelector( | |
| getTheWorkflow, | |
| // workflow still undefined, from .find() ? | |
| workflow => workflow ? workflow.name : '' | |
| ) | |
| /** OPTION 4 THROW ERROR if not found */ | |
| export getTheWorkflow = createSelector( | |
| getWorkflows, | |
| getId, | |
| (workflows, id) => { | |
| const workflow = workflows.find(workflow => workflow.id === id ) | |
| if (!workflow) { | |
| throw Error(`workflow with id: ${id} not found`) | |
| } | |
| return workflow | |
| } | |
| ) | |
| /** OPTION 5 ByID Object */ | |
| export const getWorkflowsById = createSelector( | |
| getWorkflows, | |
| workflows => workflows.reduce((workflowsById, workflow) => { | |
| workflowsById[workflow.id] = workflow | |
| return workflowsById | |
| }, {}) | |
| ) | |
| /** | |
| * @returns {?object} | |
| */ | |
| export const getTheWorkflow = createSelector( | |
| getWorkflowsById, | |
| getId, | |
| (workflowsById, id) => workflowsById[id] // technically could not be present, but clearer than .find() that it should be | |
| ) | |
| /** | |
| * @returns {string} | |
| */ | |
| export const getTheWorkflowName = createSelector( | |
| getTheWorkflow, | |
| workflow => workflow ? workflow.name : '' | |
| ) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment