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

bind:this on a transitioned element in an #each block does not properly update the bound array #6249

Open
geoffrich opened this issue Apr 27, 2021 · 7 comments

Comments

@geoffrich
Copy link
Member

Describe the bug
When you dynamically bind elements in an #each block to an array, and those elements have a transition on them, the bound array is not kept in sync when elements are removed.

This effectively means I cannot use bind:this in an each block if elements will be removed and I want to transition them out.

Logs
n/a

To Reproduce
REPL

The above REPL renders an array (vals) with four items and a button to remove each item. Each <li> is dynamically bound to an element in the items array. The items array is rendered below the list to illustrate what items are being bound.

When you remove the bottom element ("orange") from the list, items is not updated. As you continue to remove elements from bottom-to-top, items stays one step behind and is out-of-sync.

items is kept in sync if you remove items top-to-bottom. Also, if you remove the transition directive from the list item, the items array seems to be kept in sync.

Example markup (see REPL for context):

{#each vals as val, i (val)}
	<li 
		transition:scale
		bind:this={items[i]} 
		>{val} <button on:click={() =>
		remove(val, i)}>Remove</button>
	</li>
{/each}

Expected behavior
The items array should be in sync with the current state of the DOM. If I remove "orange", the associated DOM element should be removed from the array (or replaced by null/undefined).

Stacktraces
n/a

Information about your Svelte project:

  • Your browser and the version: Firefox 88.0

  • Your operating system: Windows 10

  • Svelte version: 3.37.0

  • Whether your project uses Webpack or Rollup: Rollup

Severity
This issue is annoying. I can work around it by calling querySelector, but that doesn't feel like the most idiomatic way to do it in Svelte.

For context, I encountered this issue when trying to render a list of inputs. I need to bind to each input so that I can call focus on them when one of them is removed. Since the bound array is not kept in-sync, sometimes the wrong input is focused.

Additional context
#4869 seems related, but that's related to binding components instead of DOM elements.

I encountered this bug when working on sveltejs/kit#1207.

@geoffrich
Copy link
Member Author

Also, in my REPL, if you remove the first item ("apple") then the new second item ("cranberry"), there are two items left in the vals array ("banana" and "orange"), but the bound items array only contains the "orange" element in the second spot.

@Zachiah
Copy link
Contributor

Zachiah commented Jun 5, 2021

label: triage: bug?

@stale
Copy link

stale bot commented Dec 2, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale-bot label Dec 2, 2021
@geoffrich
Copy link
Member Author

This is still a bug in the latest Svelte version.

@stale
Copy link

stale bot commented Dec 16, 2021

This issue has been closed as it was previously marked as stale and saw no subsequent activity.

@stale stale bot closed this as completed Dec 16, 2021
@homerjam
Copy link

Reopen?

@geoffrich geoffrich reopened this Jul 13, 2022
@ptrxyz
Copy link

ptrxyz commented Apr 17, 2023

Can confirm, this is still present in latest 3.58.0.

https://svelte.dev/repl/6ef0eeb08bc84f268f37281846d836e5?version=3.58.0
(as stated by the OP, remove the items from bottom to top)

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

No branches or pull requests

4 participants