Reputation: 3344
<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)
Upvotes: 1
Views: 681
Reputation: 7699
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.
<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}
<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
<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}
<script>
import { onMount } from 'svelte';
export let message;
export let deleteMessage;
onMount( () => {
setTimeout(function() {
deleteMessage();
}, 3000);
});
</script>
<div> {message} </div>
Upvotes: 0
Reputation: 3344
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}
Upvotes: 0
Reputation: 29897
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
Upvotes: 1