I am currently working on editing a post using the state manager Vuex in Vue3 with Composition API. Below is the code I have implemented:
<template>
<div class="container py-5">
<h3 class="mb-5 border-top-0 border-start-0 border-end-0 pb-3 border">
Edit Post
</h3>
<div v-if="formData.loading">
<div class="spinner-border text-primary" role="status"></div>
</div>
<form v-else @submit.prevent="validation">
<div class="form col-md-7">
<div class="mb-3">
<label for="title" class="form-label">Title</label>
<input
v-model="formData.title"
type="text"
class="form-control"
@input="formData.titleErr = false"
id="title"
placeholder="Please enter the title"
/>
<p class="my-2 text-danger" v-if="formData.titleErr">
This title is not valid
</p>
</div>
<div class="mb-3">
<label for="content" class="form-label">Content</label>
<textarea
class="form-control"
id="content"
placeholder="Please enter the content"
rows="7"
v-model="formData.content"
@input="formData.contentErr = false"
></textarea>
<p class="my-2 text-danger" v-if="formData.contentErr">
This content is not valid
</p>
</div>
<button
type="submit"
value=""
class="btn btn-primary"
@click="validation">
Edit
</button>
</div>
</form>
</div>
</template>
And here is the script:
<script>
import { computed, onMounted, reactive } from "vue";
import { useStore } from "vuex";
import { useRoute } from "vue-router";
export default {
setup() {
const store = useStore();
const formData = reactive({
title: "",
titleErr: false,
invalidTitle: true,
content: "",
contentErr: false,
invalidContent: true,
loading: false,
});
const route = useRoute();
const postInfo = computed(() => store.getters["postsModule/setSinglePost"]);
onMounted(() => {
formData.title = postInfo.value.title;
formData.content = postInfo.value.body;
});
const validation = () => {
if (formData.title === "" && formData.invalidTitle) {
formData.titleErr = true;
} else {
formData.invalidTitle = !formData.invalidTitle;
formData.titleErr = false;
}
if (formData.content === "" && formData.invalidContent) {
formData.contentErr = true;
} else {
formData.invalidContent = !formData.invalidContent;
formData.contentErr = false;
}
if (
formData.title !== "" &&
!formData.invalidTitle &&
formData.content !== "" &&
!formData.invalidContent
) {
const data = {
title: formData.title,
body: formData.content,
};
editPost(data);
}
formData.title = "";
formData.content = "";
};
return { formData, validation, postInfo };
},
};
</script>
The issue I am facing is related to the synchronization of the computed value `postInfo` obtained from the store. The initial rendering shows empty inputs and subsequent renderings display outdated data. It seems that the computed value is not updating correctly during the first render as the setup function hasn't returned anything yet.
Here is the corresponding store:
import axios from "axios";
import Swal from "sweetalert2";
const postsModule = {
namespaced: true,
state: {
posts: [],
singlePost: {},
},
getters: {
setPosts(state) {
return state.posts;
},
setSinglePost(state) {
return state.singlePost;
},
},
mutations: {
getPosts(state, posts) {
return (state.posts = posts);
},
getSingle(state, post) {
return (state.singlePost = post);
},
},
actions: {
// methods for fetching, deleting, and creating posts
},
};
export default postsModule;
Is there a solution to ensure the computed value remains synchronized across all renders?