Skip to content

Instantly share code, notes, and snippets.

@amsterdamharu
Last active March 17, 2021 19:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save amsterdamharu/50cf8bba34e163c845a98c0a7450dafe to your computer and use it in GitHub Desktop.
Save amsterdamharu/50cf8bba34e163c845a98c0a7450dafe to your computer and use it in GitHub Desktop.
import React from 'react';
export const NOT_REQUESTED = {
requested: false,
loading: false,
};
const AVAILABLE = {
requested: true,
loading: false,
};
const isResult = (value) =>
['loading', 'requested'].reduce(
// eslint-disable-next-line no-prototype-builtins
(result, key) => result && value.hasOwnProperty(key),
true
);
const asResult = (value = {}) =>
isResult(value)
? value
: {
...AVAILABLE,
value,
};
//gets the most important result that doesn't
// have value, error most important, then requested, then loading
const pickResult = (resultValues) =>
resultValues
.map((result) => [
result,
(result.error ? 1000 : 0) +
(!result.requested ? 100 : 0) +
(result.loading ? 10 : 0),
])
.reduce(
([highestItem, highest], [item, points]) =>
highest < points
? [item, points]
: [highestItem, highest],
[{}, -1]
)[0];
// skips calling passed in function if any of the values is loading or has error
export const useResults = (values) => (fn) => {
const resultValues = values.map(asResult);
return resultValues.reduce(
(available, result) =>
available &&
!result.error &&
!result.loading &&
result.requested,
true
)
? asResult(
fn(resultValues.map((result) => result.value))
)
: pickResult(resultValues);
};
export const withLoading = (Component) => ({
loading,
requested,
...props
}) =>
loading || !requested ? (
<h1>Loading</h1>
) : (
Component(props)
);
export const withError = (Component) => ({
error,
...props
}) => (error ? <h1>Error</h1> : Component(props));
export const withResult = (Component) => ({
value,
...props
}) => Component({ ...props, ...value });
export const withErrorLoading = (Component) => (props) =>
withError(withLoading(withResult(Component)))(props);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment