Proof-of-concept of a Rust-ish Result return for ember-concurrency tasks
MIT License
Proof-of-concept of a Rust-ish Result
return modifier for ember-concurrency
tasks, based on an idea Alex Machtneer floated in the Ember Community Discord.
Some of this will probably changed.
Uses Result
from true-myth
.
ember install ember-concurrency-result
task
ember-concurrency-result
adds a result
function which can wrap an
ember-concurrency TaskProperty
. You can use the addon via this wrapping
strategy like below:
// components/flaky-component.js
import Component from '@ember/component';
import { task } from 'ember-concurrency';
import { result } from 'ember-concurrency-result';
import getWidgetsFromFlakyApi from '../utils/get-widgets';
import UnavailableError from '../utils/errors/unavailable';
export default Component.extend({
myTask: result(task(function*() {
return yield getWidgetsFromFlakyApi();
})),
someMethod() {
const lastValue = this.myTask.last.value;
if (lastValue.isOk()) {
const widgets = lastValue.value;
alert(`There are ${widgets.length} widgets in the widgetry.`);
} else if (lastValue.error instanceof UnavailableError) {
alert("Those darn flaky APIs! They're at it again!");
} else {
alert('wtf.');
}
}
});
task
property modifierThe wrapping method above may not look as aesthetically pleasing, so instead, you
may also add a .result
modifier to ember-concurrency tasks through the
magic of reaching into private APIs! ember-concurrency-result
provides a
defineModifier
function that can be used somewhere early in the boot process,
such as app.js
or in an initializer, which will add a result
modifier
method to the TaskProperty
prototype.
// app.js
import defineModifier from 'ember-concurrency-result/define-modifier';
defineModifier();
// remainder of app.js...
// components/flaky-component.js
import Component from '@ember/component';
import { task } from 'ember-concurrency';
import { result } from 'ember-concurrency-result';
import getWidgetsFromFlakyApi from '../utils/get-widgets';
import UnavailableError from '../utils/errors/unavailable';
export default Component.extend({
myTask: task(function*() {
return yield getWidgetsFromFlakyApi();
}).result(),
someMethod() {
const lastValue = this.myTask.last.value;
if (lastValue.isOk()) {
const widgets = lastValue.value;
alert(`There are ${widgets.length} widgets in the widgetry.`);
} else if (lastValue.error instanceof UnavailableError) {
alert("Those darn flaky APIs! They're at it again!");
} else {
alert('wtf.');
}
}
});
Because this relies on accessing ember-concurrency
's TaskProperty
intimate
API and modifying the prototype for that object, it's not strictly recommended,
but should be relatively safe to do, as the chances of that API changing
drastically without a suitable replacement is unlikely.
See the Contributing guide for details.
This project is licensed under the MIT License.