I have this code, which displays a list of messages and should add a message that was sent by a Tauri event and update the list:
let messages: Message[] = [];
$: sortedMessages = [...messages].sort((a, b) => a.created - b.created);
.
.
.
async function getMessages() {
const newMessages = <Message[]> await invoke('get_messages', {userId: currentChatInfo?.user.id});
messages = <Message[]>[...messages, ...newMessages];
}
listen('new-message', (event) => {
const message: Message = <Message> event.payload;
if(message.userId === currentChatInfo?.user.id) {
messages = [...messages, message];
}
});
.
.
.
{#await getMessages()}
<div>loading...</div>
{:then sortedMessages}
{#each sortedMessages as message}
<MessageBox {message}/>
{/each}
{/await}
but the update/re-render doesn't happen. And I don't see why. According to the docs and StackOverflow
$: sortedMessages = [...messages].sort((a, b) => a.created - b.created);
should do the trick. But it doesn't :(
I start to suspect it's the {#await}
around the {#each}
. But I'm not sure how to test that easily. And what to do if that's the case. I don't like the idea of passing the messages as a prop to this component. As I like how self-contained it is.
Edit: Turns out I was partially right with my suspicion, see @Corrl's answer for the details.
{:then sortedMessages}
creates a new variable in the scope of the block with the result of the first getMessages()
call
Replace with
{:then _}
so that sortedMessages
inside the each block points to the reactive variable