Skip to content

Commit 301cd57

Browse files
Merge pull request #39 from NullVoxPopuli/add-template-test-for-async-functions
fix: when an async function resolves, auto-tracking should do stuff
2 parents 31eebf5 + e051be9 commit 301cd57

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

addon/-private/resources/function-runner.ts

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { isDestroyed, isDestroying } from '@ember/destroyable';
2+
import { get as consume, notifyPropertyChange as dirty } from '@ember/object';
23
import { waitForPromise } from '@ember/test-waiters';
34

45
import { LifecycleResource } from './lifecycle';
@@ -7,6 +8,8 @@ import type { ArgsWrapper } from '../types';
78

89
export const FUNCTION_TO_RUN = Symbol('FUNCTION TO RUN');
910

11+
const SECRET_VALUE = '___ Secret Value ___';
12+
1013
// type UnwrapAsync<T> = T extends Promise<infer U> ? U : T;
1114
// type GetReturn<T extends () => unknown> = UnwrapAsync<ReturnType<T>>;
1215
export type ResourceFn<Return = unknown, Args extends unknown[] = unknown[]> = (
@@ -24,9 +27,15 @@ export class FunctionRunner<
2427
Fn extends ResourceFn<Return, Args> = ResourceFn<Return, Args>
2528
> extends LifecycleResource<BaseArgs<Args>> {
2629
// Set when using useResource
27-
declare [FUNCTION_TO_RUN]: Fn;
30+
protected declare [FUNCTION_TO_RUN]: Fn;
31+
private declare [SECRET_VALUE]: Return | undefined;
32+
33+
get value(): Return | undefined {
34+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
35+
consume(this, SECRET_VALUE as any);
2836

29-
declare value: Return | undefined;
37+
return this[SECRET_VALUE];
38+
}
3039

3140
get funArgs() {
3241
return this.args.positional;
@@ -49,7 +58,8 @@ export class FunctionRunner<
4958
return;
5059
}
5160

52-
this.value = value;
61+
this[SECRET_VALUE] = value;
62+
dirty(this, SECRET_VALUE);
5363
};
5464

5565
waitForPromise(result);
@@ -60,6 +70,6 @@ export class FunctionRunner<
6070
}
6171
}
6272

63-
this.value = result;
73+
this[SECRET_VALUE] = result;
6474
}
6575
}

tests/unit/use-resource-test.ts

+30
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { hbs } from 'ember-cli-htmlbars';
77
import { module, test } from 'qunit';
88
import { setupRenderingTest, setupTest } from 'ember-qunit';
99

10+
import { timeout } from 'ember-concurrency';
1011
import { LifecycleResource, useResource } from 'ember-resources';
1112

1213
module('useResource', function () {
@@ -297,6 +298,35 @@ module('useResource', function () {
297298
assert.dom('out').hasText('2');
298299
});
299300

301+
test('async functions update when the promise resolves', async function (assert) {
302+
class Test extends Component {
303+
data = useResource(this, async () => {
304+
await new Promise((resolve) => setTimeout(resolve, 50));
305+
306+
return 2;
307+
});
308+
}
309+
310+
const TestComponent = setComponentTemplate(
311+
hbs`
312+
<out>{{this.data.value}}</out>
313+
`,
314+
Test
315+
);
316+
317+
this.setProperties({ TestComponent });
318+
319+
render(hbs`<this.TestComponent />`);
320+
321+
await timeout(25);
322+
323+
assert.dom('out').hasText('');
324+
325+
await timeout(30);
326+
327+
assert.dom('out').hasText('2');
328+
});
329+
300330
test('it works without a thunk', async function (assert) {
301331
class Test extends Component {
302332
@tracked count = 1;

0 commit comments

Comments
 (0)