Skip to content

Commit

Permalink
Merge pull request #838 from NullVoxPopuli/bring-in-trackedTask-fix
Browse files Browse the repository at this point in the history
fix: #835 incorrect value returned when last task was dropped
  • Loading branch information
NullVoxPopuli authored Mar 20, 2023
2 parents 2d69754 + acbf03d commit 0fd5d8e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 2 deletions.
6 changes: 6 additions & 0 deletions .changeset/mean-moons-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"ember-resources": patch
---

Fixes [#835](https://github.com/NullVoxPopuli/ember-resources/issues/835) - resolves regression introduced by [PR: #808 ](https://github.com/NullVoxPopuli/ember-resources/pull/808) which aimed to correctly return the _previous_ task instance's value if the _current task_ hasn't finished yet. The regression described by #835 was that if a task in cancelled (e.g.: dropped), it is considered finished, and that canceled task's value would be used instead of the last compuleted task. In normal ember-concurrency APIs, this is abstracted over via the `.lastSuccessful` property on the `TaskProperty`. The goal of the `.value` on `trackedTask` is to mimic the property chain: `taskProperty.lastSuccessful?.value`.

2 changes: 1 addition & 1 deletion ember-resources/src/util/ember-concurrency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class TaskResource<
declare lastTask: TaskInstance<Return> | undefined;

get value() {
if (this.currentTask?.isFinished) {
if (this.currentTask?.isFinished && !this.currentTask.isCanceled) {
return this.currentTask.value;
}

Expand Down
34 changes: 33 additions & 1 deletion test-app/tests/utils/ember-concurrency/js-test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { tracked } from '@glimmer/tracking';
import { settled } from '@ember/test-helpers';
import { waitFor } from '@ember/test-waiters';
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';

import { restartableTask, timeout } from 'ember-concurrency';
import { dropTask, restartableTask, timeout } from 'ember-concurrency';
import { taskFor } from 'ember-concurrency-ts';
import { trackedTask } from 'ember-resources/util/ember-concurrency';

Expand Down Expand Up @@ -168,6 +169,37 @@ module('useTask', function () {
assert.false(foo.search.isRunning);
assert.strictEqual(foo.search.value, null);
});

test('it returns correct task value when tasks have been dropped', async function (assert) {
class Test {
@tracked input = 'initial value';

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

@dropTask
@waitFor
*_search(input: string) {
yield new Promise((resolve) => setTimeout(() => resolve('')));

return input;
}
}

let foo = new Test();

// task is initiated upon first access
foo.search.value;

// immediately start another task (this will be dropped/cancelled)
foo.input = 'updated value';
foo.search.value;

await settled();

assert.strictEqual(foo.search.value, 'initial value', 'returns value from first task');
assert.true(foo.search.isFinished);
assert.false(foo.search.isRunning);
});
});
});
});

0 comments on commit 0fd5d8e

Please sign in to comment.