Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow $store to be used with changing values including nullish values #7947

Merged
merged 6 commits into from
May 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
* **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))
* **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))
* **breaking** Deprecate `SvelteComponentTyped`, use `SvelteComponent` instead ([#8512](https://github.com/sveltejs/svelte/pull/8512))
* **breaking** Error on falsy values instead of stores passed to `derived` ([#7947](https://github.com/sveltejs/svelte/pull/7947))
* Add `a11y no-noninteractive-element-interactions` rule ([#8391](https://github.com/sveltejs/svelte/pull/8391))
* Add `a11y-no-static-element-interactions`rule ([#8251](https://github.com/sveltejs/svelte/pull/8251))
* Bind `null` option and input values consistently ([#8312](https://github.com/sveltejs/svelte/issues/8312))
* Allow `$store` to be used with changing values including nullish values ([#7555](https://github.com/sveltejs/svelte/issues/7555))

## Unreleased (3.0)

Expand Down
3 changes: 3 additions & 0 deletions src/runtime/internal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ export function validate_store(store, name) {

export function subscribe(store, ...callbacks) {
if (store == null) {
for (const callback of callbacks) {
callback(undefined);
}
return noop;
}
const unsub = store.subscribe(...callbacks);
Expand Down
7 changes: 4 additions & 3 deletions src/runtime/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,10 @@ export function derived<S extends Stores, T>(

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

const auto = fn.length < 2;

Expand Down
21 changes: 21 additions & 0 deletions test/runtime/samples/store-auto-subscribe-removed-store/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { writable } from '../../../../store';

export default {
html: `
<p>undefined</p>
`,
async test({ assert, component, target }) {
component.store = writable('foo');
assert.htmlEqual(target.innerHTML, `
<p>foo</p>
`);
component.store = undefined;
assert.htmlEqual(target.innerHTML, `
<p>undefined</p>
`);
component.store = writable('bar');
assert.htmlEqual(target.innerHTML, `
<p>bar</p>
`);
}
};
ramonsnir marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script>
export let store;
</script>

<p>{$store}</p>
15 changes: 15 additions & 0 deletions test/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,21 @@ describe('store', () => {
a.set(false);
assert.equal(b_started, false);
});

it('errors on undefined stores #1', () => {
assert.throws(() => {
derived(null, (n) => n);
});
});

it('errors on undefined stores #2', () => {
assert.throws(() => {
const a = writable(1);
derived([a, null, undefined], ([n]) => {
return n * 2;
});
});
});
});

describe('get', () => {
Expand Down