Skip to content

{#key} not working inside {#each}/{#if} #6688

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

Closed
chulman444 opened this issue Aug 28, 2021 · 10 comments
Closed

{#key} not working inside {#each}/{#if} #6688

chulman444 opened this issue Aug 28, 2021 · 10 comments
Labels
bug compiler Changes relating to the compiler

Comments

@chulman444
Copy link

Describe the bug

{#key} and its body that work doesn't work inside {#each} block.

I want to display the duration passed every second by calculation instead of assigning a value to an object in an array and triggering update with assignment.

Reproduction

https://svelte.dev/repl/d4112f1ae05046bdb48be42b62cc4c8d?version=3.42.4

Logs

No response

System Info

System:
    OS: Windows 10 10.0.18363
    CPU: (8) x64 Intel(R) Core(TM) i7-3610QM CPU @ 2.30GHz
    Memory: 6.11 GB / 11.90 GB
  Binaries:
    Node: 14.16.0 - D:\Program Files\nodejs\node.EXE
    npm: 6.14.11 - D:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 91.0.4472.164
    Edge: Spartan (44.18362.1533.0)
    Internet Explorer: 11.0.18362.1
  npmPackages:
    svelte: ^3.38.2 => 3.38.2

Severity

annoyance

@Prinzhorn
Copy link
Contributor

Prinzhorn commented Aug 28, 2021

This does work in contrast (I simply output the key {force_update_heartbeat}): https://svelte.dev/repl/d2358d0e2e9c4052afad3ec85140802b?version=3.42.4
So it seems like Svelte does not add the key to the observed properties when inside each. But if it is there anyway the update works.

Edit: even with the bug fixed your REPL doesn't look Svelte-like to me. You are basically imperatively controlling the reactivity by setting force_update_heartbeat just to call foo(). If you can show a more real world example I'm sure there is a better way. Why not update the array items directly each tick? https://svelte.dev/repl/dc3ac91d693a466693a1935a96d06c73?version=3.42.4

@Mlocik97
Copy link
Contributor

it doesn't matter that this is code that has some real world usage, the point is that it doesn't work as expected, and this is clearly BUG.

even with the bug fixed your REPL doesn't look Svelte-like to me.

for me it's valid Svelte as well as for Svelte's compiler itself.

@Prinzhorn
Copy link
Contributor

I 100% agree that this is a bug and I didn't say otherwise. I'm just trying to advocate patterns that fit Svelte better than the classic approach of imperatively updating everything (jQuery, Backbone, even React to some degree).

@chulman444
Copy link
Author

@Prinzhorn

More real life example and very close to what I'm trying to do:

https://svelte.dev/repl/f5df58cacfba4c71a81b3072ae4ad955?version=3.42.4

It works when #key is outside of #each.

I don't want to store the evaluated data, "time passed" in the example" and just display it using the returned value of a function. And I'm using #key because that's a hacky way of re-evaluating the function when the expression passed to #key changes.

Besides this point, as said in the documentation (#key section link):

This is useful if you want an element to play its transition whenever a value changes.

So I also included the transition examples. Transition when #key is outside of #each but doesn't otherwise.

And I don't know what's going on but transition looks also buggy.

@Prinzhorn
Copy link
Contributor

Prinzhorn commented Sep 1, 2021

@chulman444

Here's a more Svelte-like version with a now store (ask me about stores, I love stores. Have you heard about stores?) https://svelte.dev/repl/1ce622ca561e41fe817c4b10d7351059?version=3.42.4

Edit: in a real application I'd suggest having now run just a couple of seconds ahead. Otherwise if you post an item literally now, it might show "in 1s" and not "right now" or "a moment ago" etc. because now is already outdated

@WofWca
Copy link

WofWca commented Sep 28, 2021

Also doesn't work inside {#if} and {:else}:
https://svelte.dev/repl/f7587129060b4e7eb19d6684832c963f?version=3.43.0

Update the issue title?

@dummdidumm dummdidumm added bug compiler Changes relating to the compiler labels Sep 28, 2021
@GiovannaMonti
Copy link

Also doesn't work inside {#if} and {:else}: https://svelte.dev/repl/f7587129060b4e7eb19d6684832c963f?version=3.43.0

Update the issue title?

I spent a lot of time wondering why the {#key} block I was trying to use did not work as expected. I just now found this issue and I happened to be using it inside an if. I agree that the issue should be renamed so others can find it

@dummdidumm dummdidumm changed the title {#key} not working inside {#each} {#key} not working inside {#each}/{#if} Feb 14, 2022
@optama
Copy link

optama commented Feb 23, 2022

A workaround I'm using is to add bind:this={foo} in the element inside the {#key} block. No idea why it works though.
My real world use case is to trigger an animation (out of several selected by #if) when a value changes.

@kindoflew
Copy link
Contributor

@dummdidumm
Copy link
Member

It was, thanks for noticing!

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

No branches or pull requests

8 participants