Skip to content

Populating data table from svelte kit load() in +page.ts breaks selection #707

@pboguslawski

Description

@pboguslawski

Describe the bug

After upgrading from Svelte4+SvelteKit+SMUI7 to Svelte5+SvelteKit+SMUI8 data table selection does not work if data is populated from load() in +page.ts like this:

+page.ts:

import type { PageLoad } from './$types';

let options = [
	{
		name: 'Broom',
		description: 'A wooden handled broom.',
		price: 15
	},
	{
		name: 'Dust Pan',
		description: 'A plastic dust pan.',
		price: 8
	},
	{
		name: 'Mop',
		description: 'A strong, durable mop.',
		price: 18
	},
	{
		name: 'Horse',
		description: "She's got some miles on her.",
		price: 83
	},
	{
		name: 'Bucket',
		description: 'A metal bucket.',
		price: 13
	}
];

export const load = (() => {
	return {
		options: options
	};
}) satisfies PageLoad;

+page.svelte

<script lang="ts">
	import type { PageData } from './$types';
	import DataTable, { Head, Body, Row, Cell } from '@smui/data-table';
	import Checkbox from '@smui/checkbox';

	interface Props {
		data: PageData;
	}

	let { data }: Props = $props();

	type Option = {
		name: string;
		description: string;
		price: number;
	};
	let options = $derived(data.options);

	let selected: Option[] = $state([]);

	const selectedPrice = $derived(selected.reduce((total, option) => option.price + total, 0));
</script>

<DataTable style="max-width: 100%;">
	<Head>
		<Row>
			<Cell checkbox>
				<Checkbox />
			</Cell>
			<Cell>Name</Cell>
			<Cell>Description</Cell>
			<Cell numeric>Price</Cell>
		</Row>
	</Head>
	<Body>
		{#each options as option (option.name)}
			<Row>
				<Cell checkbox>
					<Checkbox bind:group={selected} value={option} valueKey={option.name} />
				</Cell>
				<Cell>{option.name}</Cell>
				<Cell>{option.description}</Cell>
				<Cell numeric>{option.price}</Cell>
			</Row>
		{/each}
	</Body>
</DataTable>

<pre class="status">Selected: {selected.map((option) => option.name).join(', ')}</pre>
<pre class="status">Total: {selectedPrice}</pre>

Try to select all and deselect all using table header checkbox - selected won't be empty and

[svelte] state_proxy_equality_mismatch
Reactive `$state(...)` proxies and the values they proxy have different identities. Because of this, comparisons with `===` will produce unexpected results
https://svelte.dev/e/state_proxy_equality_mismatch

message is generated in browser console.

No such problem if options is defined using $state in +page.svelte file like in Row selection example.

Selection in data table populated from load() in +page.ts worked fine in Svelte4+SvelteKit+SMUI7.

Expected behavior
Data table selection should work correctly if data is populated from load() in +page.ts (i.e. with async fetch)

Desktop (please complete the following information):

  • OS: Debian 13
  • Browser Firefox 140.6.0esr

@smui/data-table: 8.0.3
svelte: 5.45.10
@sveltejs/kit: 2.49.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions