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).
$inspect(waypointsBearings)
as is intended, you can seeenabled
,angle
°rees
change on interaction, what else did you expect?$inspect
. But if I try to use$effect
to react to those changes, then I don't see it triggering. The$effect
on the line 41. Inspect by itself is not very useful, when it comes to something except debugging...