Skip to content

Commit e852687

Browse files
Merge pull request #608 from danwenzel/fix-keep-latest-is-empty
fix(util, keepLatest): isEmpty logic was incorrect for objects, arrays, and 0
2 parents a00dc8d + 8d377c1 commit e852687

File tree

2 files changed

+144
-3
lines changed

2 files changed

+144
-3
lines changed

ember-resources/src/util/keep-latest.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ const isEmpty = (x: undefined | unknown | unknown[]) => {
88
if (typeof x === 'object') {
99
if (x === null) return true;
1010

11-
return x || Object.keys(x).length > 0;
11+
return Object.keys(x).length === 0;
1212
}
1313

14-
return Boolean(x);
14+
return x !== 0 && !x;
1515
};
1616

1717
interface Options<T = unknown> {

testing/ember-app/tests/utils/keep-latest/js-test.ts

+142-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { keepLatest } from 'ember-resources/util/keep-latest';
1010
module('Utils | keepLatest | js', function (hooks) {
1111
setupTest(hooks);
1212

13-
test('it works', async function (assert) {
13+
test('it works with a trackedFunction', async function (assert) {
1414
class Test {
1515
@tracked x = 1;
1616

@@ -45,4 +45,145 @@ module('Utils | keepLatest | js', function (hooks) {
4545
await timeout(40);
4646
assert.strictEqual(instance.data, 2);
4747
});
48+
49+
test('it works if the value gets reset to undefined while loading', async function (assert) {
50+
class Test {
51+
@tracked isLoading = false;
52+
@tracked value?: number = 3;
53+
54+
@use data = keepLatest({
55+
when: () => this.isLoading,
56+
value: () => this.value,
57+
});
58+
}
59+
60+
let instance = new Test();
61+
62+
assert.strictEqual(instance.data, 3);
63+
64+
instance.isLoading = true;
65+
instance.value = undefined;
66+
67+
assert.strictEqual(instance.data, 3);
68+
});
69+
70+
test('it works with array values correctly', async function (assert) {
71+
class Test {
72+
@tracked isLoading = false;
73+
@tracked value = ['a'];
74+
75+
@use data = keepLatest({
76+
when: () => this.isLoading,
77+
value: () => this.value,
78+
});
79+
}
80+
81+
let instance = new Test();
82+
83+
assert.deepEqual(instance.data, ['a']);
84+
85+
instance.isLoading = true;
86+
87+
instance.value = ['b'];
88+
89+
assert.deepEqual(instance.data, ['b'], 'still returns the current value if it is not empty');
90+
91+
instance.value = [];
92+
93+
assert.deepEqual(
94+
instance.data,
95+
['b'],
96+
'returns the previous value if the current value is empty'
97+
);
98+
});
99+
100+
test('it works with object values correctly', async function (assert) {
101+
class Test {
102+
@tracked isLoading = false;
103+
@tracked value: Record<string, unknown> = { x: 3 };
104+
105+
@use data = keepLatest({
106+
when: () => this.isLoading,
107+
value: () => this.value,
108+
});
109+
}
110+
111+
let instance = new Test();
112+
113+
assert.deepEqual(instance.data, { x: 3 });
114+
115+
instance.isLoading = true;
116+
117+
instance.value = { y: 4 };
118+
119+
assert.deepEqual(instance.data, { y: 4 }, 'still returns the current value if it is not empty');
120+
121+
instance.value = {};
122+
123+
assert.deepEqual(
124+
instance.data,
125+
{ y: 4 },
126+
'returns the previous value if the current value is empty'
127+
);
128+
});
129+
130+
test('it works with string values correctly', async function (assert) {
131+
class Test {
132+
@tracked isLoading = false;
133+
@tracked value = 'one';
134+
135+
@use data = keepLatest({
136+
when: () => this.isLoading,
137+
value: () => this.value,
138+
});
139+
}
140+
141+
let instance = new Test();
142+
143+
assert.deepEqual(instance.data, 'one');
144+
145+
instance.isLoading = true;
146+
147+
instance.value = 'two';
148+
149+
assert.deepEqual(instance.data, 'two', 'still returns the current value if it is not empty');
150+
151+
instance.value = '';
152+
153+
assert.deepEqual(
154+
instance.data,
155+
'two',
156+
'returns the previous value if the current value is empty'
157+
);
158+
});
159+
160+
test('it works with number values correctly', async function (assert) {
161+
class Test {
162+
@tracked isLoading = false;
163+
@tracked value: number | null = 1;
164+
165+
@use data = keepLatest({
166+
when: () => this.isLoading,
167+
value: () => this.value,
168+
});
169+
}
170+
171+
let instance = new Test();
172+
173+
assert.deepEqual(instance.data, 1);
174+
175+
instance.isLoading = true;
176+
177+
instance.value = 2;
178+
179+
assert.deepEqual(instance.data, 2, 'still returns the current value if it is not empty');
180+
181+
instance.value = 0;
182+
183+
assert.deepEqual(instance.data, 0, 'does not treat 0 as empty');
184+
185+
instance.value = null;
186+
187+
assert.deepEqual(instance.data, 0, 'returns the previous value if the current value is null');
188+
});
48189
});

0 commit comments

Comments
 (0)