Skip to content

Commit ea73930

Browse files
fix: allow $store to be used with changing values including nullish values (#7947)
fixes #7555 breaking change: derived now throws an error if you pass falsy values --------- Co-authored-by: Simon Holthausen <[email protected]>
1 parent d083f8a commit ea73930

File tree

6 files changed

+50
-3
lines changed

6 files changed

+50
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
* **breaking** Stricter types for `onMount` - now throws a type error when returning a function asynchronously to catch potential mistakes around callback functions (see PR for migration instructions) ([#8136](https://github.com/sveltejs/svelte/pull/8136))
1111
* **breaking** Overhaul and drastically improve creating custom elements with Svelte (see PR for list of changes and migration instructions) ([#8457](https://github.com/sveltejs/svelte/pull/8457))
1212
* **breaking** Deprecate `SvelteComponentTyped`, use `SvelteComponent` instead ([#8512](https://github.com/sveltejs/svelte/pull/8512))
13+
* **breaking** Error on falsy values instead of stores passed to `derived` ([#7947](https://github.com/sveltejs/svelte/pull/7947))
1314
* Add `a11y no-noninteractive-element-interactions` rule ([#8391](https://github.com/sveltejs/svelte/pull/8391))
1415
* Add `a11y-no-static-element-interactions`rule ([#8251](https://github.com/sveltejs/svelte/pull/8251))
1516
* Bind `null` option and input values consistently ([#8312](https://github.com/sveltejs/svelte/issues/8312))
17+
* Allow `$store` to be used with changing values including nullish values ([#7555](https://github.com/sveltejs/svelte/issues/7555))
1618

1719
## Unreleased (3.0)
1820

src/runtime/internal/utils.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ export function validate_store(store, name) {
6868

6969
export function subscribe(store, ...callbacks) {
7070
if (store == null) {
71+
for (const callback of callbacks) {
72+
callback(undefined);
73+
}
7174
return noop;
7275
}
7376
const unsub = store.subscribe(...callbacks);

src/runtime/store/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ export function derived<S extends Stores, T>(
164164

165165
export function derived<T>(stores: Stores, fn: Function, initial_value?: T): Readable<T> {
166166
const single = !Array.isArray(stores);
167-
const stores_array: Array<Readable<any>> = single
168-
? [stores as Readable<any>]
169-
: stores as Array<Readable<any>>;
167+
const stores_array: Array<Readable<any>> = single ? [stores as Readable<any>] : stores as Array<Readable<any>>;
168+
if (!stores_array.every(Boolean)) {
169+
throw new Error('derived() expects stores as input, got a falsy value');
170+
}
170171

171172
const auto = fn.length < 2;
172173

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { writable } from '../../../../store';
2+
3+
export default {
4+
html: `
5+
<p>undefined</p>
6+
`,
7+
async test({ assert, component, target }) {
8+
component.store = writable('foo');
9+
assert.htmlEqual(target.innerHTML, `
10+
<p>foo</p>
11+
`);
12+
component.store = undefined;
13+
assert.htmlEqual(target.innerHTML, `
14+
<p>undefined</p>
15+
`);
16+
component.store = writable('bar');
17+
assert.htmlEqual(target.innerHTML, `
18+
<p>bar</p>
19+
`);
20+
}
21+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<script>
2+
export let store;
3+
</script>
4+
5+
<p>{$store}</p>

test/store/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,21 @@ describe('store', () => {
428428
a.set(false);
429429
assert.equal(b_started, false);
430430
});
431+
432+
it('errors on undefined stores #1', () => {
433+
assert.throws(() => {
434+
derived(null, (n) => n);
435+
});
436+
});
437+
438+
it('errors on undefined stores #2', () => {
439+
assert.throws(() => {
440+
const a = writable(1);
441+
derived([a, null, undefined], ([n]) => {
442+
return n * 2;
443+
});
444+
});
445+
});
431446
});
432447

433448
describe('get', () => {

0 commit comments

Comments
 (0)