Skip to content

Commit bdc3392

Browse files
Merge pull request #836 from rpemberton/rp/fix-incorrect-task-value
fix: incorrect value returned when last task was dropped
2 parents e9d2ad0 + f708824 commit bdc3392

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

.changeset/mean-moons-grab.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"ember-resources": patch
3+
---
4+
5+
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`.
6+

ember-resources/src/util/ember-concurrency.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ export class TaskResource<
214214
declare lastTask: TaskInstance<Return> | undefined;
215215

216216
get value() {
217-
if (this.currentTask?.isFinished) {
217+
if (this.currentTask?.isFinished && !this.currentTask.isCanceled) {
218218
return this.currentTask.value;
219219
}
220220

testing/ember-app/tests/utils/ember-concurrency/js-test.ts

+33-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { tracked } from '@glimmer/tracking';
33
import { settled } from '@ember/test-helpers';
4+
import { waitFor } from '@ember/test-waiters';
45
import { module, test } from 'qunit';
56
import { setupTest } from 'ember-qunit';
67

7-
import { restartableTask, timeout } from 'ember-concurrency';
8+
import { dropTask, restartableTask, timeout } from 'ember-concurrency';
89
import { taskFor } from 'ember-concurrency-ts';
910
import { trackedTask } from 'ember-resources/util/ember-concurrency';
1011

@@ -168,6 +169,37 @@ module('useTask', function () {
168169
assert.false(foo.search.isRunning);
169170
assert.strictEqual(foo.search.value, null);
170171
});
172+
173+
test('it returns correct task value when tasks have been dropped', async function (assert) {
174+
class Test {
175+
@tracked input = 'initial value';
176+
177+
search = trackedTask(this, taskFor(this._search), () => [this.input]);
178+
179+
@dropTask
180+
@waitFor
181+
*_search(input: string) {
182+
yield new Promise((resolve) => setTimeout(() => resolve('')));
183+
184+
return input;
185+
}
186+
}
187+
188+
let foo = new Test();
189+
190+
// task is initiated upon first access
191+
foo.search.value;
192+
193+
// immediately start another task (this will be dropped/cancelled)
194+
foo.input = 'updated value';
195+
foo.search.value;
196+
197+
await settled();
198+
199+
assert.strictEqual(foo.search.value, 'initial value', 'returns value from first task');
200+
assert.true(foo.search.isFinished);
201+
assert.false(foo.search.isRunning);
202+
});
171203
});
172204
});
173205
});

0 commit comments

Comments
 (0)