Svelte: slot inside #if inside #each : TypeError cannot read property 'd' of null

Created on 4 May 2019  路  7Comments  路  Source: sveltejs/svelte

REPL link

<script>
  let show = true;
  setTimeout(() => (show = false));
</script>

<div>
  {#each [""] as v (v)}
     {#if show}<slot></slot>{/if}
  {/each}
</div>

Running this causes an error when an update is triggered by the reactive assignment in setTimeout:
Chrome: Uncaught (in promise) TypeError: Cannot read property 'd' of null
Safari: Unhandled Promise Rejection: TypeError: null is not an object (evaluating 'if_block.d')

If the each block is not keyed (I remove (v)), there's no error.

Most helpful comment

Such an intricate bug. Great find!

The change handler of the each block has this code in it:

p(changed, ctx) {
  // ...
  group_outros();
  on_outro(() => {
    if_block.d(1);
    if_block = null;
  });

  if_block.o(1);
  check_outros();
}

And the change handler of the entire component has this code in it:

p(changed, ctx) {
  // ...
  each_blocks = update_keyed_each(/* ... */);
  check_outros();
}

When show is changed the check_outros in the each block change handler is called and it sets if_block to null, so when the component check_outros is called directly after, if_block is null and the error is thrown.

All 7 comments

Such an intricate bug. Great find!

The change handler of the each block has this code in it:

p(changed, ctx) {
  // ...
  group_outros();
  on_outro(() => {
    if_block.d(1);
    if_block = null;
  });

  if_block.o(1);
  check_outros();
}

And the change handler of the entire component has this code in it:

p(changed, ctx) {
  // ...
  each_blocks = update_keyed_each(/* ... */);
  check_outros();
}

When show is changed the check_outros in the each block change handler is called and it sets if_block to null, so when the component check_outros is called directly after, if_block is null and the error is thrown.

I've had the same errors in keyed each which contain if with svelte:self inside.
Maybe, we can just add null-checks to on_outro callbacks?

I did try to add some null-checks to on_outro in IfBlock. Hope it's right way to fix this issue.

I'm getting this error in a keyed each with an if block which contains a component:
https://svelte.dev/repl/f737684ba6534637901724ce9daca33f?version=3.4.4

Steps to reproduce:

  1. Click the submit button
  2. Then click the reset button

JS error in Console: TypeError: if_block is null.
(Removing the key avoids the issue.)

The only workaround I've found to get around this issue is to move the

{#if shown}...{/if}

into the component.

Just ran into the same variation as @fvsch. Here's a slightly smaller reproduction of the issue:

https://svelte.dev/repl/35fdcf7ddad1403abf3ec6eeee108e57?version=3.4.4

Note that the problem goes away if you remove the key (item) or don't use a component (say, replace <Item></Item> with <li></li>).

All three of the reproductions in this issue look to be fixed in 3.6.7, presumably by #3172. Closing.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Rich-Harris picture Rich-Harris  路  3Comments

Rich-Harris picture Rich-Harris  路  3Comments

1u0n picture 1u0n  路  3Comments

juniorsd picture juniorsd  路  3Comments

ricardobeat picture ricardobeat  路  3Comments