Skip to content

Commit

Permalink
Merge pull request #93 from universal-ember/thennable-trackedTask
Browse files Browse the repository at this point in the history
Make trackedTask reactively thennable, so that integrations with thennables are automatically reactive
  • Loading branch information
NullVoxPopuli authored Mar 23, 2024
2 parents 264c8c3 + 214f839 commit 1d7ea37
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
7 changes: 6 additions & 1 deletion reactiveweb/src/ember-concurrency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,16 @@ export class State<Args extends any[], Return, LocalTask extends TaskIsh<Args, R

if (key === 'value') {
/**
* getter than falls back to the previous task's value
* getter that falls back to the previous task's value
*/
return taskRunner.value;
}

// We can be thennable, but we'll want to entangle with tracked data
if (key === 'then') {
get(taskRunner.currentTask, 'isRunning');
}

/**
* If the key is anything other than value, query on the currentTask
*/
Expand Down
42 changes: 42 additions & 0 deletions tests/test-app/tests/utils/ember-concurrency/rendering-test.gts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { setupRenderingTest } from 'ember-qunit';

import { restartableTask, timeout } from 'ember-concurrency';
import { trackedTask } from 'reactiveweb/ember-concurrency';
import { trackedFunction } from 'reactiveweb/function';

let version = '^3.0.0';

Expand Down Expand Up @@ -71,6 +72,47 @@ module('useTask', function () {
window.onerror = onError;
});

test('is reactively thennable', async function (assert) {
class Test {
@tracked input = 'Hello there';

_search = restartableTask(async (input: string) => {
await timeout(100);
assert.step('resolved rt');

return input;
});
search = trackedTask(this, this._search, () => [this.input]);

wrappedSearch = trackedFunction(this, async () => {
let result = await this.search;

assert.step(`tf:${result}`);

return String(result);
});
}

let ctx = new Test();

render(<template>{{ctx.wrappedSearch.value}}</template>);

// This could introduce flakiness / timing issues
await timeout(10);

assert.dom().hasNoText();

await settled();

assert.dom().hasText('Hello there');
assert.verifySteps(['resolved rt', 'tf:Hello there', 'tf:Hello there'], 'tracked function over-dirties due to consuming a task');

ctx.input = 'General Kenobi';
await settled();
assert.dom().hasText('General Kenobi');
assert.verifySteps(['resolved rt', 'tf:General Kenobi', 'tf:General Kenobi'], 'tracked function over-dirties due to consuming a task');
});

test('error', async function (assert) {
setupOnerror((error: any) => {
assert.ok(
Expand Down

0 comments on commit 1d7ea37

Please sign in to comment.