reactiveweb
    Preparing search index...

    Function getPromiseState

    • 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.

      Type Parameters

      • Value
      • Result = ResolvedValueOf<Value>

      Returns State<Result>

      We can use getPromiseState to dynamically load and render a component

      import { getPromiseState } from 'reactiveweb/get-promise-state';

      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';
      import { getPromiseState } from 'reactiveweb/get-promise-state';

      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';
      import { getPromiseState } from 'reactiveweb/get-promise-state';

      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.

      . reactiveweb @warpdrive/ember
      use in module state[1]
      use in a getter[2]
      usable in template
      immediate has resolved value for resolved promise
      invokes a passed function automatically
      avoids addons using private APIs [3]
      test waiter integration
      no dependencies[4] [5]
      simple state return[6] [7]

      all in all, they are very similar. The primary use case I had for creating my own is that I wanted dynamic module loading (with import) to be one line (shown in the first example).

      reactiveweb's getPromiseState is made primarily for my needs in my own projects, and I don't intend to say anything negative about @warp-drives getPromiseState -- I actually took a lot of code from it! it's a good tool.


      1. getPromiseState(promise); ↩︎

      2. requires a stable reference to a promise. getter itself does not need to be cached. ↩︎

      3. @warp-drive/ember declares an optional peer dependency on ember-provide-consume-context, which uses private apis, and we don't want to support usage of private APIs. ↩︎

      4. warp-drive requires a macros config that isn't compatible with "non-config" projects (it's mostly how they generate macros to not gracefully have some behavior if you don't set up their required babel config -- which affects REPL environments (this is solveable via pushing the responsibility to configure babel to the REPLer)). Also, the warp-drive team says this is on their radar, and the'll address it eventually / soon. ↩︎

      5. reactiveweb (as a whole) does depend on on ember-resources, but ember-resources itself has no dependencies (for real), and is a very tiny use of a helper manager. Additionally, getPromiseState does not depend on ember-resources. ↩︎

      6. in reactiveweb: State, and then in @warp-drive/*: the PromiseState is made of 3 sub types: PendingPromise, ResolvedPromise, and RejectedPromise ↩︎

      7. warp-drive provides many aliases for states, as well as support some extended promise behavior which is not built in to the platform (Futures, etc). This is still good for convenience and compatibility. ↩︎