datatables icon indicating copy to clipboard operation
datatables copied to clipboard

[Runes] ownership_invalid_mutation

Open icheered opened this issue 1 year ago • 2 comments

In the "Hello World" example using ThSort or ThFilter triggers the warning

[svelte] ownership_invalid_mutationnode_modules/@vincjo/datatables/dist/src/shared/ThSort.svelte mutated a value owned by src/lib/components/table.svelte. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead

This only triggers in dev mode, in production mode this does not trigger a warning.

icheered avatar Sep 16 '24 10:09 icheered

I guess i should create a new project with a npm i @vincjo/datatables and test it properly.

Thanks for the warning, will fix it for sure

vincjo avatar Sep 16 '24 13:09 vincjo

Hey, getting same here. Looks like its called by children components updating the parent table. Here is my code:

+page.svelte

const table = new TableHandler(visitLogs, { rowsPerPage: 10 });

aside class="flex gap-2">
	<input
		type="text"
		class="input border-secondary-500"
		bind:value={search.value}
		oninput={() => search.set()}
		placeholder="Filter logs..."
	/>
	<HeaderFilter {table} key="client" />
	<HeaderFilter {table} key="assignee" />
	{#if table.filters.length > 0}
		<button type="button" class="btn variant-ghost-error" onclick={() => table.clearFilters()}>
			<span>Reset</span>
			<span>
				<svg
					xmlns="http://www.w3.org/2000/svg"
					fill="none"
					viewBox="0 0 24 24"
					stroke-width="1.5"
					stroke="currentColor"
					class="size-6"
				>
					<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
				</svg>
			</span>
		</button>
	{/if}
</aside>

<div class="table-container space-y-4">
	<table class="table table-hover table-compact table-auto w-full">
		<thead>
			<tr>
				<ThSort {table} field="client">Client</ThSort>
				<ThSort {table} field="assignee">Carer</ThSort>
				<ThSort {table} field="note">Note</ThSort>
			</tr>
		</thead>
		<tbody>
			{#each table.rows as row}
				<tr>
					<td>{row.client}</td>
					<td>{row.assignee}</td>
					<td>{row.note || 'No note'}</td>
				</tr>
			{/each}
		</tbody>
	</table>
	<footer class="flex justify-between">
		<RowCount {table} />
		<Pagination {table} />
	</footer>
</div>

and the child component

HeaderFilter.svelte

<script lang="ts">
	import { camelCaseToWords } from '$lib/utils/text';
	import { popup } from '@skeletonlabs/skeleton';
	import type { PopupSettings } from '@skeletonlabs/skeleton';
	import type { TableHandler } from '@vincjo/datatables';

	type Props = { table: TableHandler; key: string };
	let { table, key }: Props = $props();

	const distinct = table.createCalculation(key).distinct({ sort: ['count', 'desc'] });
	const search = table.createRecordFilter(distinct);
	const filter = table.createAdvancedFilter(key);

	const target = `popupClick-${key}`;

	const popupClick: PopupSettings = {
		event: 'click',
		target,
		placement: 'bottom',
		closeQuery: '#will-close'
	};
</script>

<button class="btn variant-filled-secondary" use:popup={popupClick}>{camelCaseToWords(key)}</button>

<div class="card p-4 variant-filled-secondary max-w-xs z-1000 fixed" data-popup={target}>
	<input
		type="text"
		class="input mb-2"
		bind:value={search.value}
		oninput={() => search.set()}
		placeholder={camelCaseToWords(key)}
	/>
	<div class="max-h-64 overflow-y-auto">
		{#each search.records as { value }}
			<button
				class="block"
				onclick={() => filter.set(value)}
				class:active={filter.criteria.includes(value)}
			>
				<label class="flex items-center space-x-2">
					<input class="checkbox" type="checkbox" checked={filter.criteria.includes(value)} />
					<span>{value}</span>
				</label>
			</button>
		{/each}
		{#if filter.criteria.length > 0}
			<hr />
			<button type="button" class="btn !bg-transparent" onclick={() => filter.clear()}>
				Clear filters</button
			>
		{/if}
	</div>
</div>

Error is:

[svelte] ownership_invalid_mutationsrc/lib/components/logchecker/datatable/HeaderFilter.svelte mutated a value owned by src/lib/components/logchecker/datatable/PreClassificationDatatable.svelte. This is strongly discouraged. Consider passing values to child components with bind:, or use a callback instead

jaycoolslm avatar Nov 04 '24 11:11 jaycoolslm