I'm working on a Vue js 3 project using typescript and Pinia.
I have a modal that creates a changelog it works well, the changelog is created but the view is not updated, I need to refresh the page to be displayed.
<template>
<div class="flex px-4">
<CreateChangelogModal/>
</div>
<main>
<div class="grid grid-cols-1 gap-4 place-items-center mt-10 md:mt-28">
<template v-if="changelogStore.filteredChangelogs?.length">
<ChangelogCard
class="mb-2.5"
v-for="changelog in changelogStore.filteredChangelogs"
:id="changelog.id"
:date="changelog.date"
:type="changelog.type"
:title="changelog.title"
:app_name="changelog.app_name"
:content="changelog.content"
:key="changelog.id"
/>
</template>
<div v-else class="text-center p-4">
<p>No changelogs to display</p>
</div>
</div>
</main>
</template>
<script setup lang="ts">
const changelogStore = useChangelogStore()
onMounted(async () => {
if (changelogStore.changelogs.length === 0) {
await changelogStore.fetchChangelogs()
}
})
</script>
My store, changelogsStore.ts :
export const useChangelogStore = defineStore('changelogs', {
state: () => ({
changelogs: [] as ChangelogInterface[],
searchQuery: ''
}),
getters: {
filteredChangelogs: (state) => {
const searchLower = state.searchQuery.toLowerCase()
return state.changelogs.filter((changelog) => {
return changelog.title.toLowerCase().includes(searchLower) ||
changelog.date.includes(searchLower) ||
changelog.type.toLowerCase().includes(searchLower)
})
}
},
actions: {
setSearchQuery(newQuery: string) {
this.searchQuery = newQuery
},
async fetchChangelogs(lastChangelogId?: number) {
try {
const newChangelogs = await changelogService.getAllChangelogs(lastChangelogId)
if (newChangelogs.length > 0) {
this.changelogs.push(...newChangelogs)
}
return newChangelogs
} catch (error) {
console.error('Failed to fetch changelogs:', error)
return []
}
},
async generateChangelog(changelogData: ChangelogInterface) {
try {
const newChangelog = await changelogService.createChangelog(changelogData)
console.log('FROM THE STORE GENERATE CHANGELOG' ,changelogData)
this.changelogs.push(newChangelog)
} catch (error) {
console.error('Failed to create changelog:', error)
}
},
And the form that creates the changelog (not sure if the problem comes from there but just to be sure) :
<script lang="ts" setup>
const changelogUseCase = new ChangelogsUsecases()
const createChangelog = async (formData: ChangelogInterface) => {
try {
const newChangelog = await changelogUseCase.createChangelog(formData)
if (newChangelog) {
// NOT SO SURE ABOUT changelogStore.changelogs.push(newChangelog)
// changelogStore.fetchChangelogs(newChangelog.id)
}
} catch (error) {
console.error('Error while creating new changelog :', error)
}
}
const onSubmit = handleSubmit(async (values) => {
const validData: ChangelogInterface = {
title: values.title,
type: values.type,
date: values.date,
content: values.content,
app_name: values.app_name
}
await createChangelog(validData)
})
</script>
I tried to only display the code needed that could be the issue.
Thanks !
I found where the problem was, when manipulating array in Vue some operations on arrays may break reactivity, in my store I had :
this.changelogs.push(...[newChangelog])
But with this it's finally working as intended !
this.changelogs.splice(...[newChangelog])
Thank you @Boris for your kind help !