Type alias Thunk<Args>

Thunk<Args>: (() => []) | (() => void) | (() => undefined) | (() => ThunkReturnFor<Args>["positional"]) | (() => ThunkReturnFor<Args>["named"]) | (() => Partial<ThunkReturnFor<Args>>) | (() => ThunkReturnFor<Args>)

A generic function type that represents the various formats a Thunk can be in.

  • The thunk is "just a function" that allows tracked data to be lazily consumed by the resource.

Note that thunks are awkward when they aren't required -- they may even be awkward when they are required. Whenever possible, we should rely on auto-tracking, such as what trackedFunction provides.

So when and why are thunks needed?

  • when we want to manage reactivity separately from a calling context.
  • in many cases, the thunk is invoked during setup and update of various Resources, so that the setup and update evaluations can "entangle" with any tracked properties accessed within the thunk. This allows changes to those tracked properties to cause the Resources to (re)update.

The args thunk accepts the following data shapes:

() => [an, array]
() => ({ hello: 'there' })
() => ({ named: {...}, positional: [...] })

An array

when an array is passed, inside the Resource, this.args.named will be empty and this.args.positional will contain the result of the thunk.

for function resources, this is the only type of thunk allowed.

An object of named args

when an object is passed where the key named is not present, this.args.named will contain the result of the thunk and this.args.positional will be empty.

An object containing both named args and positional args

when an object is passed containing either keys: named or positional:

  • this.args.named will be the value of the result of the thunk's named property
  • this.args.positional will be the value of the result of the thunk's positional property

This is the same shape of args used throughout Ember's Helpers, Modifiers, etc

For fine-grained reactivity

you may opt to use an object of thunks when you want individual properties to be reactive -- useful for when you don't need or want to cause whole-resource lifecycle events.

() => ({
foo: () => this.foo,
bar: () => this.bar,

Inside a class-based Resource, this will be received as the named args. then, you may invoke named.foo() to evaluate potentially tracked data and have automatic updating within your resource based on the source trackedness.

class MyResource extends Resource {
modify(_, named) { this.named = named };

get foo() {
return this.named.foo();

Type Parameters

Generated using TypeDoc