Skip to content

Commit

Permalink
fix: trackedTask returns correct last value
Browse files Browse the repository at this point in the history
  • Loading branch information
sergey-zhidkov authored and NullVoxPopuli committed Mar 9, 2023
1 parent bd634bc commit 34884c2
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .changeset/many-brooms-turn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"ember-resources": patch
---

`trackedTask` must return correct last value.

Fixes the issue described at #793
If the task was called multiple times and the last returned value was null or undefined,
then trackedTask will return the previous value instead of the current one.
6 changes: 5 additions & 1 deletion ember-resources/src/util/ember-concurrency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ export class TaskResource<
declare lastTask: TaskInstance<Return> | undefined;

get value() {
return this.currentTask.value ?? this.lastTask?.value;
if (this.currentTask?.isFinished) {
return this.currentTask.value;
}

return this.lastTask?.value;
}

modify(positional: Args) {
Expand Down
61 changes: 61 additions & 0 deletions testing/ember-app/tests/utils/ember-concurrency/js-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,67 @@ module('useTask', function () {
assert.false(foo.search.isRunning);
assert.deepEqual(foo.search.value, { results: ['Hello there!'] });
});

test('it returns correct task value if "task" function returned "undefined" or "null"', async function (assert) {
class Test {
@tracked input: string | undefined | null = 'initial value';

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

@restartableTask
*_search(input: string | undefined | null) {
// or some bigger timeout for an actual search task to debounce
yield timeout(0);

// or some api data if actual search task
return input;
}
}

let foo = new Test();

// task is initiated upon first access
foo.search;
await settled();

assert.strictEqual(foo.search.value, undefined);
assert.false(foo.search.isFinished);
assert.true(foo.search.isRunning);

await settled();

assert.true(foo.search.isFinished);
assert.false(foo.search.isRunning);
assert.strictEqual(foo.search.value, 'initial value');

// "trackedTask" must return "undefined" as current (latest) value
foo.input = undefined;
await settled();

assert.strictEqual(foo.search.value, 'initial value', 'previous value is retained');
assert.false(foo.search.isFinished);
assert.true(foo.search.isRunning);

await settled();

assert.true(foo.search.isFinished);
assert.false(foo.search.isRunning);
assert.strictEqual(foo.search.value, undefined);

// "trackedTask" must return "null" as current (latest) value
foo.input = null;
await settled();

assert.strictEqual(foo.search.value, undefined, 'previous value is retained');
assert.false(foo.search.isFinished);
assert.true(foo.search.isRunning);

await settled();

assert.true(foo.search.isFinished);
assert.false(foo.search.isRunning);
assert.strictEqual(foo.search.value, null);
});
});
});
});

0 comments on commit 34884c2

Please sign in to comment.