Optional
modifythis lifecycle hook is called whenever arguments to the resource change. This can be useful for calling functions, comparing previous values, etc.
the two arguments, positional
, and named
will always be present, and
can be assigned to properties on the class to use derived-from-args patterns.
For example,
export class MyResource extends Resource {
modify(positional, named) {
this.positional = positional;
this.named = named;
}
get foo() {
return this.named.foo;
}
}
both the positional
and named
properties don't need to be tracked, because the
objects they are set to are tracked internally -- and between modify
calls,
they are actually the same object. So in this example, after the first time modify
is called, any subsequent calls to modify
will be no-ops.
This strategy is good for fine-grained reactivity in your resource because it allows
your args to be individually consumed as needed. In the above example, accessing foo
will entangle with the named arg, foo, so when that named arg changes, updates to your UI
accessing MyResource's foo getter will also update, accordingly.
Static
fromFor 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(() => [ ... ]);
}
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
});
}
Generated using TypeDoc
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).When would you reach for the class-based
Resource
instead of the function-basedresource
?the capabilities of the function-based resource and class-based resource are almost identical. the main difference is that function-based resources may represent a single a value (which could, itself, be a class instance, or object with properties), class-based-resources expose the whole class instance to the consumer.
function-based resources, however, are much easier to work with and understand, and have better intellisense capabilities.
An example
Once defined, there are two ways to use
MyResource
In the template, the Resource can be imported (or re-exported from the helpers directory)
When imported (using RFC 779),
When using in javascript, you'll need the
from
utilityHowever, when authoring a Resource, it's useful to co-locate an export of a helper function:
This way, consumers only need one import.
If your resource may be used with other resources in the same file, class-based resources also work with use, which gives the benefit of omitting the
this
parameter tofrom
.