We can use getPromiseState
to dynamically load and render a component
let state = getPromiseState(() => import('./some-module/component'));
<template>
{{#if state.isLoading}}
... pending ...
{{else if state.error}}
oh no!
{{else if state.resolved}}
<state.resolved />
{{/if}}
</template>
getPromiseState
can also be used in a class without @cached
, because it maintains its own cache.
import Component from '@glimmer/component';
async function readFromSomewhere() { // implementation omitted for brevity
}
export default class Demo extends Component {
// doesn't matter how many times state is accessed, you get a stable state
get state() {
return getPromiseState(readFromSomewhere);
}
<template>
{{#if this.state.resolved}}
...
{{/if}}
</template>
}
A reactively constructed function will also be used and have its result cached between uses
import Component from '@glimmer/component';
async function readFromSomewhere() { // implementation omitted for brevity
}
export default class Demo extends Component {
// Note: the @cached is important here because we don't want repeat accesses
// to cause doAsync to be called again unless @id changes
@cached
get promise() {
return this.doAsync(this.args.id);
}
get state() {
return getPromiseState(this.promise);
}
<template>
{{#if this.state.resolved}}
...
{{/if}}
</template>
}
NOTE: This getPromiseState
is not a replacement for WarpDrive's getRequestState
namely, the getPromiseState
in this library (reactiveweb) does not support futures, cancellation, or anything else specific to warp-drive.
Returns a reactive state for a given value, function, promise, or function that returns a promise.
Also caches the result for the given value, so
getPromiseState
will become synchronous if the passed value has already been resolved.Normally when trying to derive async state, you'll first need to invoke a function to get the promise from that function's return value. With
getPromiseState
, a passed function will be invoked for you, so you can skip that step.