Quantcast
Channel: Active questions tagged svelte - Stack Overflow
Viewing all articles
Browse latest Browse all 1734

How to fix non-reactive nested objects inside a $state([]) in Svelte?

$
0
0

Here's the link to repro (Svelte Playground).

The problem is that when you add a "waypoint" and toggle the checkbox to enable its bearings (thus changing the respective nested object's enabled property), Svelte won't see these changes. I can see that because the effect on the lines 41-44 won't log anything. If I use $inpsect instead, there's also nothing.

let { directions, configuration } = {directions: {waypointsBearings: [], configuration: {bearings: true}}, on: () => {}, configuration: {}}  // @ts-expect-error It's safe to read the plugin's protected properties here.  if (!directions.configuration.bearings) {    console.warn("The Bearings Control is used, but the `bearings` configuration option is not enabled!");  }    function addWaypoint() {        directions.waypointsBearings.push({enabled: false})        onWaypointsChanged()    }  let waypointsBearings: {    enabled: boolean;    angle: number;    degrees: number;  }[] = $state([]);  // directions.on("addwaypoint", onWaypointsChanged);  // directions.on("removewaypoint", onWaypointsChanged);  // directions.on("movewaypoint", onWaypointsChanged);  // directions.on("setwaypoints", onWaypointsChanged);  function onWaypointsChanged() {    waypointsBearings = directions.waypointsBearings.map((waypointBearing, index) => {      if (waypointsBearings[index]) return waypointsBearings[index];      return {        enabled: configuration.defaultEnabled || !!waypointBearing,        angle: waypointBearing ? waypointBearing[0] : configuration.angleDefault,        degrees: waypointBearing          ? waypointBearing[1]          : configuration.fixedDegrees            ? configuration.fixedDegrees            : configuration.degreesDefault,      };    });  }  $effect(() => {    console.log("PIA");    console.log(waypointsBearings);  });  onWaypointsChanged();

(The addWaypoint function is artifical and serves to replace the commented-out directions.on calls. It's here just to replace the real map and its interactivity).

<button onclick={addWaypoint}>Add</button><div class="bearings-control {configuration.class}" style="display: {waypointsBearings.length ? 'block' : 'none'}"><div class="bearings-control__list">    {#each waypointsBearings as waypointBearing, i}<div        class="        bearings-control__list-item        {waypointBearing.enabled ? 'bearings-control__list-item--enabled' : 'bearings-control__list-item--disabled'}"><span class="bearings-control__number">{i + 1}. </span><input type="checkbox" bind:checked={waypointBearing.enabled} class="bearings-control__checkbox" />

I assume that this absence of reactivity for the inner objects is just a part of the broader issue (see the context below), but should be enough to start.

Here's some broader context for the problem. I have a working code (Svelte 4) which I'm trying to rewrite to Svelte 5. You can see the working Svelte 4 code here and you can see it in action (see that it actually works fine) here (try clicking the map to add waypoints, so that the "bearings" bar appears).


Viewing all articles
Browse latest Browse all 1734

Trending Articles