Class TaskResource<Args, Return, LocalTask>

The 'Resource' base class has only one lifecycle hook, modify, which is called during instantiation of the resource as well as on every update of any of any consumed args.

Typically, a Resource will be used to build higher-level APIs that you'd then use in your apps. For example, maybe you want to build a reactive-wrapper around a non-reactive wrapper, XState which requires that the "State machine interpreter" is stopped when you are discarding the parent context (such as a component).

An example

import { Resource } from 'ember-resources';
import { createMachine, interpret } from 'xstate';

const machine = createMachine(); // ... see XState docs for this function this ...

class MyResource extends Resource {
@tracked customState;

constructor(owner) {
super(owner);

registerDestructor(this, () => this.interpreter.stop());
}

modify(positional, named) {
if (!this.interpreter) {
// Initial Setup
this.interpreter = interpret(machine).onTransition(state => this.customState = state);
} else {
// Subsequent Updates
this.interpreter.send('SOME_EVENT', { positional, named });
}
}
}

Once defined, there are two ways to use MyResource

  • in a template
  • in JavaScript

In the template, the Resource can be imported (or re-exported from the helpers directory)

When imported (using RFC 779),

import { MyResource } from './somewhere';

<template>
{{#let (MyResource) as |myResource|}}
{{log myResource.customState}}
{{/let}}
</template>

When using in javascript, you'll need the from utility

import { MyResource } from './somewhere';

class ContainingClass {
state = MyResource.from(this, () => [...])
}

However, when authoring a Resource, it's useful to co-locate an export of a helper function:

export function myResource(destroyable, options) {
return MyResource.from(destroyable, () => ({
foo: () => options.foo,
bar: () => options.bar,
}))
}

This way, consumers only need one import.

Type Parameters

  • Args extends any[]

  • Return

  • LocalTask extends TaskIsh<Args, Return>

Hierarchy

  • Resource<{ positional: Args }>
    • TaskResource

Constructors

Properties

Accessors

Methods

Constructors

  • new TaskResource<Args, Return, LocalTask>(owner: unknown): TaskResource<Args, Return, LocalTask>
  • Type Parameters

    • Args extends any[]

    • Return

    • LocalTask extends TaskIsh<Args, Return, LocalTask>

    Parameters

    • owner: unknown

    Returns TaskResource<Args, Return, LocalTask>

Properties

[TASK]: LocalTask
currentTask: TaskInstance<Return>
lastTask: undefined | TaskInstance<Return>

Accessors

  • get value(): undefined | null | Return
  • Returns undefined | null | Return

Methods

  • modify(positional: Args): void
  • this lifecycle hook is called whenever arguments to the resource change. This can be useful for calling functions, comparing previous values, etc.

    Parameters

    • positional: Args

    Returns void

  • teardown(): void
  • Returns void

  • from<SomeResource>(this: Constructor<SomeResource>, thunk: AsThunk<ArgsFrom<SomeResource>, ThunkReturnFor<ArgsFrom<SomeResource>>>): SomeResource
  • from<SomeResource>(this: Constructor<SomeResource>, context: unknown, thunk: AsThunk<ArgsFrom<SomeResource>, ThunkReturnFor<ArgsFrom<SomeResource>>>): SomeResource
  • For use in the body of a class.

    from is what allows resources to be used in JS, they hide the reactivity APIs from the consumer so that the surface API is smaller.

    import { Resource, use } from 'ember-resources';

    class SomeResource extends Resource {}

    class MyClass {
    @use data = SomeResource.from(() => [ ... ]);
    }

    Type Parameters

    • SomeResource extends Resource<any, SomeResource>

    Parameters

    • this: Constructor<SomeResource>
    • thunk: AsThunk<ArgsFrom<SomeResource>, ThunkReturnFor<ArgsFrom<SomeResource>>>

    Returns SomeResource

  • For use in the body of a class.

    from is what allows resources to be used in JS, they hide the reactivity APIs from the consumer so that the surface API is smaller. Though it may be more convenient to not wrap your resource abstraction in a helper function.

    import { Resource } from 'ember-resources';

    class SomeResource extends Resource {}

    class MyClass {
    data = SomeResource.from(this, () => [ ... ]);
    }

    However, if you have argument defaults or need to change the shape of arguments depending on what ergonomics you want your users to have, a wrapper function may be better.

    export function someResource(context, { foo, bar }) {
    return SomeResource.from(context, () => ... );
    }

    usage:

    import { someResource } from 'your-library';

    class SomeResource extends Resource {}

    class MyClass {
    @tracked foo;
    @tracked bar;

    data = someResource(this, {
    foo: () => this.foo,
    bar: () => this.bar
    });
    }

    Type Parameters

    • SomeResource extends Resource<any, SomeResource>

    Parameters

    • this: Constructor<SomeResource>
    • context: unknown
    • thunk: AsThunk<ArgsFrom<SomeResource>, ThunkReturnFor<ArgsFrom<SomeResource>>>

    Returns SomeResource

Generated using TypeDoc