ember-async v0.1.0
Ember Async
A collection of components and helpers for handling async data in Ember.
Installation
ember install ember-async
Usage
Async-View Component
The async-view
component is a higher-order component providing support for
deferred value resolution using promises, rendering different views for the
different promise states.
When passed a value, if the value is a promise, a pending view is rendered until the promise settles. If the promise fulfills successfully, then this component yields to its block expression; if the promise is rejected, an error view is displayed. If the value passed is not a promise, it is rendered immediately by yielding to its block expression.
When yielding to the block expression, both the fulfilledValue
and state
are
passed; when yielding to a pending or rejected component, the original value
and state
are passed (thus allowing the reason
to be retrieved from a
rejected promise).
Using this component, the fulfilledValue
is guaranteed to be the resolved
value from the promise, or be undefined, thus allowing components that require
an actual model instance (such as ember-form-for
when getting a localized
string) to work correctly.
Note: This component has been designed for values that implement Ember.PromiseProxyMixin, such as models returned from a store. Regular promises are not yet supported.
Using default configuration
{{#async-view model as |loadedModel|}}
{{my-form loadedModel}}
{{#/async-view}}
Configuring with parameters
{{#async-view model
pendingMessage="Fetching..."
rejectedMessage="Oops! Something went wrong"
as |loadedModel|}}
{{my-form loadedModel}}
{{#/async-view}}
{{#async-view model
pendingComponent=(component "spinner")
rejectedComponent=(component "error-message")
as |loadedModel|}}
{{my-form loadedModel}}
{{#/async-view}}
Configuring with environment
If using async-view
throughout an application, it can be convenient to specify
configuration information globally. This can be done through the environment
under the key async-view
within the ember-async
section.
Use the component in a template the same as with the default configuration:
{{#async-view model as |loadedModel|}}
{{my-form loadedModel}}
{{#/async-view}}
Then specify your options in the app configuration:
ENV['ember-async'] = {
'async-view': {
'pendingComponent': 'spinner',
'rejectedMessage': 'Oops! An error occurred'
}
}
If you specify any parameters in a template, they will override the parameters specified in the configuration.
Positional Parameters
value
The value to resolve.
Named Parameters
pendingClass
The class name to use on the element wrapping the pendingMessage
or
pendingComponent
. Defaults to async-view--pending
.
pendingMessage
The message to display while a promise is pending. Ignored if
pendingComponent
is specified. Defaults to Loading...
.
pendingComponent
The component to render while a promise is pending. Can be set to either a
component instance, or the name of the component. Passed value
and state
as
positional parameters.
rejectedClass
The class name to use on the element wrapping the rejectedMessage
or
rejectedComponent
. Defaults to async-view--rejected
.
rejectedMessage
The message to display when a promise is rejected. Ignored if
rejectedComponent
is specified. If neither rejectedMessage
or
rejectedComponent
are specified, then the message from the reason for the
rejection will be displayed.
rejectedComponent
The component to render when a promise is rejected. Can be set to either a
component instance, or the name of the component. Passed value
and state
as
positional parameters.
Positional Block Variables
fulfilledValue
If value
is a promise, the resolved value of that promise once it is
fulfilled; otherwise, if the promise remains pending or was rejected,
undefined
. If value
is not a promise, then returns value
.
state
An object representing the state of the promise containing four properties:
isPending
, isSettled
, isFulfilled
and isRejected
.
Styling
When a promise is pending or rejected, the message or component is wrapped in a
div
using the class name async-view--pending
or async-view--rejected
,
respectively.
When this component yields to its block expression, it does so without extra DOM elements, so no styling can be applied.
Async Computed Properties
asyncComputed
asyncComputed
allows properties that need to be calculated asynchronously to
update templates when they resolve. Using asyncComputed
also enables to you
await on computed properties to get their resolved value.
Use the same syntax with asyncComputed
as you would with computed
, but pass
in an async function:
user: asyncComputed('userId', async function() {
let data = await this.get('store').findRecord('user', this.get('userId'));
// transform data
return data;
})
Or use the get/set syntax with asyncComputed
:
user: asyncComputed('userId', {
async get() {
let data = await this.get('store').findRecord('user', this.get('userId'));
// transform data
return data;
},
async set(key, value) {
let updatedValue = await saveValue(value);
return updatedValue;
}
})
asyncGet
If you need to await on nested async computed properties, or regular computed
properties that are returning promises (e.g. by returning the result of
findRecord
), then use asyncGet
to await each property in the path to ensure
you get the final resolved value.
For instance:
let accounts = await asyncGet(this, 'user.accounts');
is equivalent to:
let user = await get(this, 'user');
let accounts = user ? await get(user, 'accounts') : undefined;
And solves the problem of user
not being awaited on when this is done:
let accounts = await get(this, 'user.accounts');
Related Libraries
ember-promise-helpers
Provides helpers for handling async data within templates.
ember-async-button
A button whose state reflects the state of a promise returned from a closure action, e.g. for updating the text based on the state of saving a form.
Authors
Legal
© 2017 Crunchy Bananas, LLC
Licensed under the MIT license