Skip to content

Push to array inside SvelteMap not reactive #14409

@tinnyw

Description

@tinnyw

Describe the bug

Hi friends, hope you are well! I am working on an app that deals with complex objects to store state. In one of these objects I modify a map with one of the entries in the map yielding an array for the value which I push to. Updating this array does not cause a reactive state change in the UI that depends on it. This seems unintuitive to me since I thought that objects were deeply reactive with recursive monitoring for state change.

To make this reactive I have to delete the SvelteMap entry of the key that contains the array value and set it back again with the array.

Reproduction

App.svelte

<script>
	import {bob} from "./bob.svelte.js"
	
	let name = $state('world');
	let newKid = 1
</script>

<button onclick={
	() => bob.attribs.set('type', 'friend')}
	>Bob type: {bob.attribs.get('type')}
</button>
<br/>
<br/>
<button onclick={() => {
	// Expecting just the next line that's commented to work
	/*bob.attribs.get('kids').push(newKid)*/
	const kids = bob.attribs.get('kids')
	kids.push(newKid++)
	bob.updateKids()
}}>
	Kids are: 
	{#each bob.attribs.get('kids') as kid}
		<li>{kid}</li>
	{/each}
</button>

bob.svelte.js

import {SvelteMap} from 'svelte/reactivity';

class Bob {
	attribs = $state(new SvelteMap([['type', 'employee'],
																 ['kids', ['a', 'b', 'c']]]));

	updateKids() {
		const kids = this.attribs.get('kids')
		this.attribs.delete('kids')
		this.attribs.set('kids', kids)
	}
}

export const bob = new Bob();

Logs

No response

System Info

Able to replicate this on the Svelte playground and in Ubuntu WSL.

Severity

blocking an upgrade

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions