element-vir
Version:
Heroic. Reactive. Declarative. Type safe. Web components without compromise.
45 lines (44 loc) • 1.78 kB
JavaScript
import { check } from '@augment-vir/assert';
import { extractErrorMessage } from '@augment-vir/common';
/**
* Given a {@link AsyncProp} instance, call and return the output of the `resolutionRender` parameter
* once the {@link AsyncProp} has been resolved, call and return the output of the `errorRender`
* parameter if the {@link AsyncProp} errored out, return the `fallback` parameter in all other
* cases.
*
* This is the full function definition and implementation.
*
* @category Async
*/
// eslint-disable-next-line @virmator/prefer-params-object
export function renderAsync(asyncProp,
/** This value will be rendered if the async prop has not settled yet. */
fallback, resolutionRender, errorRender, options = {}) {
const asyncPropValue = options.useLastResolvedValue
? asyncProp.lastResolvedValue
: asyncProp.value;
if (asyncPropValue instanceof Error) {
const errorResult = errorRender
? errorRender(asyncPropValue)
: extractErrorMessage(asyncPropValue);
return errorResult;
}
else if (check.isPromiseLike(asyncPropValue) ||
/**
* `lastResolvedValue` is `undefined` both before the first resolution and when the value
* genuinely resolved to `undefined`. Only the former is a loading state, so a still-pending
* `value` is what distinguishes them.
*/
(options.useLastResolvedValue &&
asyncPropValue === undefined &&
check.isPromiseLike(asyncProp.value))) {
const fallbackResult = fallback;
return fallbackResult;
}
else {
const resolutionResult = resolutionRender
? resolutionRender(asyncPropValue)
: asyncPropValue;
return resolutionResult;
}
}