Svelte: running {#await} inside an {#if}

Created on 25 May 2018  Â·  8Comments  Â·  Source: sveltejs/svelte

REPL

If we have a {#await} block running inside a truthy {#if} and, for some reason, the {#if} evaluates to false while the promise is still running, we get an error:

Uncaught (in promise) TypeError: Cannot read property 'removeChild' of null
    at detachNode (eval at createComponent (repl.1.js:1), <anonymous>:296:19)
    at Object.destroy [as d] (eval at createComponent (repl.1.js:1), <anonymous>:116:6)
    at update (eval at createComponent (repl.1.js:1), <anonymous>:332:17)
    at promise.then.value (eval at createComponent (repl.1.js:1), <anonymous>:347:5)
bug

Most helpful comment

Fixed at last in 3.6.3

All 8 comments

I think it makes sense to work on this right after or alongside #1514, because that's going to touch the await block code anyway. I just have yet to find a way of dealing with that issue that I'm happy with.

Using svelte": "2.13.2"

I'm facing same issue:

{#if $someStoreData}
  <componentA />
{:else}
  <componentB />
  <componentC />
{/if}

Initially, componentB and componentC are rendered. On $someStoreData becoming true, componentA is getting rendered fine. But the other components are creating trouble by getting destroyed twice. So, second time when it starts to destroy, it throws error: Cannot read property 'removeChild' of null.

Any idea, how to resolve?


I tried the same thing with following:

{#await promise}
    <ComponentA />
{:then answer}
         <ComponentB />
         <Component C/>
{:catch error}
         <ComponentB />
         <Component C/>>
{/await}

<script>
    export default {
        data() {
            return {
                promise: new Promise(fulfil => {
                    setTimeout(() => fulfil(42), 3000);
                })
            };
        }
    };
</script>

Same issue is there. It tries to remove the element twice.

In the following code:

  function detachNode(node) {
    node.parentNode.removeChild(node);
  }

First time when it detaches Node, node is getting destroyed rightly but it automatically tries to detach second time as well. 2nd time when it does, it is Text Node:

image

Issue also comes with await example in documentation.

After few hours of trying, got a resolution.
Solution:
Wrap those elements inside div element. Therefore:

<div>
  {#if $someStoreData}
    <ComponentA />
  {:else}
    <ComponentB />
    <ComponentC />
  {/if}
</div>

Why?
I tried to go for alternate solution, which was:

{#if $someStoreData}
  <componentA />
{/if}
<!-- Inside corresponding files for below, as per condtion, add class to "display:none" -->
<componentB />
<componentC />

Results were same, but it popped up different error this time, which was of insertBefore of null. It essentially wanted some DOM to be present. Once, it also gave error on removeChild of null which was node.parentNode(target..). It essentially meant that it was trying to find relative paths corresponding to node (other Component)in the same file. So, only solution was to wrap it in parent div, so it doesn't have to find relative path w.r.t other siblings which were getting removed, hence error.

How's the progress on this? I've just been avoiding {#await} in Svelte 3, cause the wrapping div fix no longer works.

You may be able to apply this quick hack to get the project running: https://github.com/sveltejs/svelte/issues/2086#issuecomment-490989491

The original gist is 404ing — does anyone know if it's still happening, and can repro?

IIRC the original repro - converted into v3 - was something like this:

<script>
    let promise = new Promise(res => setTimeout(res, 2000));
    let flag = true;
    setTimeout(() => flag = false, 1000);
</script>

{#if flag}
    {#await promise then _}DONE{/await}
{/if}

which does seem to still be an issue. We're trying to do target.insertBefore when target is null.

Fixed at last in 3.6.3

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matt3224 picture matt3224  Â·  3Comments

noypiscripter picture noypiscripter  Â·  3Comments

1u0n picture 1u0n  Â·  3Comments

AntoninBeaufort picture AntoninBeaufort  Â·  3Comments

rob-balfre picture rob-balfre  Â·  3Comments