Research
Security News
Malicious PyPI Package ‘pycord-self’ Targets Discord Developers with Token Theft and Backdoor Exploit
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
ember-async-await-helper
Advanced tools
Awaits a promise, then yields its result to a block. 👌
ember install ember-async-await-helper
The {{#async-await}}
template helper takes a promise as a positional parameter, a block to render once the promise is resolved. Once the promise is resolved, the helper yields the promise's result to the block.
{{#async-await this.users as |users|}}
<UserList @users={{users}} />
{{/async-await}}
If the passed in value is not a promise, it will be converted to one using Promise.resolve()
.
Optionally, you can pass an inverse block to be displayed while the promise is pending.
{{#async-await this.users as |users|}}
<UserList @users={{users}} />
{{else}}
<LoadingSpinner />
{{/async-await}}
In general, it's a bad idea to pass a fallible promise into the template. By default, if your promise rejects, {{#async-await}}
calls Ember.onerror
, which should trigger your typical error handling paths, such as showing a "something went wrong..." screen and/or reporting to Bugsnag.
The default error object comes with a reason
property set to the promise's rejection reason:
Ember.onerror = function(error) {
console.error(error.message); // => Unhandled promise rejection in {{#async-await}}: **rejection reason**
console.error(error.reason); // => **rejection reason**
};
Note that after the promise rejects, the {{#async-await}}
helper will remain in the "pending" state (i.e. the {{else}}
block).
In order to avoid dealing with rejections in the template, it is recommended that you wrap your promises in an async function that handles any expected error scenarios, so that the promise is (mostly) infallible:
export default Component.extend({
users: computed(async function() {
let retries = 0;
while (retries < 5) {
try {
return await fetch('/users.json');
} catch (e) {
if (isNetworkError(e)) {
retries += 1;
} else {
// Unexpected Error! We can let this trigger the default
// `onReject` callback. In our `Ember.onerror` handler,
// we will transition the app into a generic error route.
throw e;
}
}
}
})
});
For any non-trivial functionality, you may also want to consider using an ember-concurrency task instead. Read on for how to use the {{#async-await}}
helper together with ember-concurrency.
onReject
callbacksWhile the above method is recommended, it is also possible to pass an onReject
callback to run when the promise rejects:
{{#async-await this.users onReject=handleError as |users|}}
<UserList @users={{users}} />
{{/async-await}}
As mentioned above, after the promise rejects, the {{#async-await}}
helper will remain in the "pending" state (i.e. the {{else}}
block). Your rejection handler can retry the original operation by replacing the promise passed to the {{#async-await}}
helper:
export default Component.extend({
// ...
handleError(reason) {
if (isNetworkError(reason)) {
// retry the fetch
this.set('users', fetch('/users.json'));
} else {
// show a "something went wrong" modal
handleUnexpectedError(reason);
}
}
});
Finally, if you really want to, you can also pass null
to silence the rejections completely:
{{#async-await this.users onReject=null as |users|}}
<UserList @users={{users}} />
{{/async-await}}
ember-concurrency
Did you know that ember-concurrency
tasks (TaskInstance
s to be exact) are also promise-like objects (they have a .then
method on them). That means, you can await them with the {{#async-await}}
just like any other promises!
export default Component.extend({
init() {
this._super(...arguments);
this.fetchUsers.perform();
},
users: alias('fetchUsers.last'),
fetchUsers: task(function * () {
let retries = 0;
while (retries < 5) {
try {
return yield fetch('/users.json');
} catch (e) {
if (isNetworkError(e)) {
retries += 1;
} else {
// this will trigger the default `onReject`
throw e;
}
}
}
}).restartable()
});
With this setup, you can continue to pass this.users
to the {{#async-await}}
helper as you normally would:
{{#async-await this.users as |users|}}
<UserList @users={{users}} />
{{else}}
<LoadingSpinner />
{{/async-await}}
See the Contributing guide for details.
This project is licensed under the MIT License.
FAQs
The default blueprint for ember-cli addons.
The npm package ember-async-await-helper receives a total of 2,141 weekly downloads. As such, ember-async-await-helper popularity was classified as popular.
We found that ember-async-await-helper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.