Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Svelte 5: Regression since 5.0.0-next.162 with #each or render #12211

Open
jamesst20 opened this issue Jun 27, 2024 · 1 comment
Open

Svelte 5: Regression since 5.0.0-next.162 with #each or render #12211

jamesst20 opened this issue Jun 27, 2024 · 1 comment

Comments

@jamesst20
Copy link

jamesst20 commented Jun 27, 2024

Describe the bug

The bug started in next.162. The bug is not present in next.160. (161 appears to no longer exist)

This most likely relates to: #11836

Ok, this is going to be very hard to explain as I couldn't understand it very well myself.

I have an #each block that doesn't render at all but only under very specific circonstances.

This is the exact code:

Note: Component FlexibleFieldValueForm recursively re-render FieldValueForm

FieldValueForm.svelte

{#snippet form()}
  <div class="flex flex-col p-4 gap-4">
    This does render: {fieldValue.subfieldValues.map((f) => f.id).join(", ")}
    {#each fieldValue.subfieldValues as subfieldValue, i (subfieldValue)}
      {#if subfieldValue.field.type === FieldType.GROUP}
        <svelte:self bind:fieldValue={fieldValue.subfieldValues[i]} />
      {:else if subfieldValue.field.type === FieldType.FLEXIBLE}
        <FlexibleFieldValueForm bind:fieldValue={fieldValue.subfieldValues[i]} />
      {:else if subfieldValue.field.type === FieldType.TEXT}
        <FormInput
          bind:value={subfieldValue.value as string}
          errors={subfieldValue.errors?.value}
          label={subfieldValue.field.label}
          type="text"
        />
      {:else}
        <span class="bg-red-400 px-3 py-2 rounded-lg text-white font-semibold">
          Unknown field type: {subfieldValue.field.type}
        </span>
      {/if}
    {/each}
  </div>
{/snippet}

{#if !hideGroup}
  <Collapse {draggable} open={true} title={fieldValue.field.label}>
    {@render form()}
  </Collapse>
{:else}
  {@render form()}
{/if}

Capture d’écran, le 2024-06-27 à 12 58 51

As you can see, I have the ID 9531 in the array but nothing comes out of the #each block.

However, if in the each block I add this text to debug

{#each fieldValue.subfieldValues as subfieldValue, i (subfieldValue)}
   Rendering index: {i} <-- this line

It renders everything perfectly:

Capture d’écran, le 2024-06-27 à 13 00 52

Now... let's complexify things:

This is a Ruby on Rails project setup with ruby-vite and using InertiaJS.

  1. If I'm running the vite dev server bin/vite dev the issue is not present.
  2. I receive the payload from the backend. I noticed that if I remove the state.snapshot(post) it doesn't happen. I also noticed that the bug is also present if I create a copy with a trick like JSON.parse(JSON.stringify(post))
let { post }: Props = $props(); // fieldValues are `post.fieldValues`
let data = $derived($state.snapshot(post));

{#each data.fieldValues as _fieldValue, i (data.postGroup.postType.id)}
    <FieldValueForm fieldValue={data.fieldValues[i]} />
    <FormButton class="w-fit">Save</FormButton>
  {/each}
  1. I have also noticed that if I change the key of the #each to something like
Before:
{#each fieldValue.subfieldValues as subfieldValue, i (subfieldValue)}
After:
{#each fieldValue.subfieldValues as subfieldValue, i (subfieldValue.id)}

the bug is also not present. However I don't have IDs until the database is saved.

  1. The weirdest of all. In one of the branch condition, there is a component named FlexibleFieldValueForm that is rendered. Inside that components there is a loop that renders back the same previous component FieldValueForm with its "flexible" child values.
<FormSortableList class="gap-2" items={fieldValue.subfieldValues}>
  {#snippet children(_item, i)}
    <div class="flex">
      <FieldValueForm bind:fieldValue={fieldValue.subfieldValues[i]} draggable={true} />
      <Button class="rounded-none" color="danger" onclick={() => removeField(i)} size="sm">
        <i class="fa-solid fa-trash my-auto"></i>
      </Button>
    </div>
  {/snippet}
</FormSortableList>

Changing that code to this will fix the issue

  {#each fieldValue.subfieldValues as item, i }
    <div class="flex">
      <FieldValueForm bind:fieldValue={fieldValue.subfieldValues[i]} draggable={true} />
      <Button class="rounded-none" color="danger" onclick={() => removeField(i)} size="sm">
        <i class="fa-solid fa-trash my-auto"></i>
      </Button>
    </div>
  {/each}

but changing it to a single line and forcing index 0 wont.

<FieldValueForm bind:fieldValue={fieldValue.subfieldValues[0]} draggable={true} />

Reproduction

This is a private project and I was unable to extract it into a smaller reproduction project. I am still willing to colaborate as much as possible without violating the rights i'm being put under. Let me know if I can provide with anything

Logs

No response

System Info

System:
    OS: macOS 14.5
    CPU: (12) arm64 Apple M3 Pro
    Memory: 130.06 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
    Yarn: 1.22.22 - ~/.nvm/versions/node/v20.11.0/bin/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v20.11.0/bin/npm
    pnpm: 9.4.0 - ~/Library/pnpm/pnpm
    Watchman: 2024.04.22.00 - /opt/homebrew/bin/watchman
  Browsers:
    Chrome: 126.0.6478.127
    Safari: 17.5
  npmPackages:
    svelte: 5.0.0-next.162 => 5.0.0-next.162

Severity

blocking all usage of svelte

@jamesst20 jamesst20 changed the title Svelte 5: Regression since 5.0.0-next.162 Svelte 5: Regression since 5.0.0-next.162 with #each or render Jun 27, 2024
@trueadm
Copy link
Contributor

trueadm commented Jun 28, 2024

I believe #12215 should fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants