1
<script> 
   let myMessages = ["msg1", "msg2", "msg3"]
</script>

{#each myMessages as message}
    <div>{message}</div>
{/each}

I would like to remove each element from myMessages once it has been added on DOM so at the end myMessages is empty?
(a variation on this would be to add a {#if} condition in the loop and remove only if element satisfy this condition)

4
  • Your template reflects the states of your component/properties. If you remove element of myMessages, then the DOM will changes. So what you are asking is not a good idea. Commented May 18, 2020 at 11:15
  • @JérémieB Isn't reactivity goal to adapt DOM to state changes ? When I push new elements to myMessages, they are updated to DOM, it is a normal behaviour and that's exactly what Svelte is designed for no ? So if you have reactivity with push you would expect same reactivity with pop. I may miss something though.
    – comte
    Commented May 19, 2020 at 14:08
  • You want to update the DOM when an element is removed from myMessages ? Your question was about updating myMessages once the DOM is rendered Commented May 19, 2020 at 16:55
  • @JérémieB, you are correct. My question was more how to know when DOM is updated, so I can pop rendered item from my variable. I guess I have to assume it is guaranteed.
    – comte
    Commented May 26, 2020 at 8:54

3 Answers 3

1

Svelte's reactivity system is based on the assignment operator =
Mutations to the array ( with methods like with pop() ) are not detected.

myMessages.pop()
myMessages = myMessages // this line will trigger svelte to update the dom
0

In absence of feedback on DOM rendering I would assume it. So, to render msg1 and pop it afterwards, I would proceed as follows:

<script> 
  let myMessages = []
  let tmpMessages = myMessages
  # then add msg1 to myMessages, render it and pop it
  myMessages.push("msg1")
  tmpMessages = myMessages
  myMessages.pop()
</script>

{#each tmpMessages as message}
  <div>{message}</div>
{/each}
0

This could be achieved by creating a Message Component which dispatches its own deletion (removal from the array) to the parent App when created/mounted. Like this even more Messages could be added to the myMessages array later on with the same functionality.

Demo REPL

[App.svelte]
<script>
  import { onMount } from 'svelte';
  import Message from './Message.svelte'
    
  let myMessages = ["msg1", "msg2", "msg3"]

// add two additional Messages 1,5s after App creation  
onMount( () => {
    setTimeout(function() {
      myMessages = [...myMessages, "msg4","msg5"];
    }, 1500);
});
    
function deleteMessage(event){
    myMessages = myMessages.slice(1)
    console.log(myMessages)
}   
</script>

{#each myMessages as message}
    <Message {message} on:delete={deleteMessage}/>
{/each}
[Message.svelte]
<script>
    import { onMount } from 'svelte';
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();

    export let message;
    
onMount( () => {
    setTimeout(function() {
      dispatch('delete', {          
        });
    }, 3000);
}); 
</script>

<div> {message} </div>

Or alternatively, since there is no information dispatched but only the deletion triggered, without the dispatching like this -> Demo REPL

[App.svelte]
<script>
    import { onMount } from 'svelte';
  import Message from './Message.svelte'
    
    let myMessages = ["msg1", "msg2", "msg3"]
    
// add two additional Messages 1,5s after App creation 
onMount( () => {
    setTimeout(function() {
      myMessages = [...myMessages, "msg4","msg5"];
    }, 1500);
});
    
function deleteMessage() {
    // delete first element in arr
    myMessages = myMessages.slice(1)
    console.log(myMessages)
}   
    
</script>

{#each myMessages as message}
    <Message {message} {deleteMessage} />
{/each}
[Message.svelte]
<script>
    import { onMount } from 'svelte';
    
    export let message;
    export let deleteMessage;
    
onMount( () => {
    setTimeout(function() {
        deleteMessage();
    }, 3000);
}); 
</script>

<div> {message} </div>

Not the answer you're looking for? Browse other questions tagged or ask your own question.