In the setup function, the composition API calculates the return value of the computed property before it is

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?

Answer №1

If you're incorporating async calls within your setup, consider modifying the setup to an async setup and then utilizing await on those internal async calls to ensure that the data is fully loaded prior to being returned to your template. Remember to include a Suspense tag in the parent component. For further insight into this solution, check out the following helpful post: Why did I get blank (empty) content when I used async setup() in Vue.js 3?

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the steps for implementing middleware that relies on a socket connection?

Using express.io, I am currently working on creating a middleware that necessitates a connection to a remote server through two sockets. However, I have encountered an issue. var net = require('net'); module.exports = function (host, port) { ...

The script fails to execute on content loaded through AJAX in Django

I have a website with nested div elements that make up a complete set. These elements can be dynamically loaded when the user clicks the "load more" button. The website includes a script that changes the style of the aforementioned div element when the pa ...

The modal fails to display when the content is positioned below a setInterval function

i have created a notification system using ajax currently, I am attempting to open a modal by clicking on the content of the notification with setInterval the modal works perfectly when the content of my notification is not being updated via setInterval. ...

Creating unique geometric designs with three.js

Attempting to construct a polygon in three.js and here is the code used for it. function DeployZone(coordinatesList) { // Forming the polygon Shape { var material = new THREE.MeshLambertMaterial({ color: 0x00ffcc }); var faces = [0, 1, 2, 3, 4] ...

Tips for embedding text into a doughnut chart with primeng/chart.js

Currently tackling a primeng chart project involving the development of a doughnut chart within angular. The task at hand is to display text inside the doughnut chart, aligning with the designated design vision. Referencing the image below for visualizatio ...

To enable the description p tag only when the search box text matches the search criteria, otherwise keep the p tag disabled

I need to develop a search feature that includes a search box, a heading, and a paragraph description. Initially, the description should be hidden, but when a user enters text that matches the description, the paragraph tag should become visible. An exampl ...

A guide to accessing the innerHTML of a div using React

My current setup involves creating an editable-content field as shown below const Input = () => { const Enter = () => { ... } const Editable = () => ( <div className={"editable"} contentEditable={"true"}> This i ...

Prompt for action following button activation

My goal is to set the focus on an input field when a button is clicked. I am attempting to do this by using a local directive called v-directive. However, I am encountering difficulties in getting the directive to apply properly after the button is clicked ...

Update image source dynamically using AJAX and jQuery

Within my app, there exists a web page that contains numerous images with dynamically generated source URLs obtained by sending get requests to the rails server. Initially, these images are assigned a default source. Upon loading the page, another request ...

Laravel 8 not passing CSRF token to Vue.js

I am attempting to create a file uploader using vuejs within laravel 8. To achieve this, I have included the following meta tag: <meta name="csrf-token" content="{{ csrf_token() }}"> However, I continue to encounter error 419. Be ...

Tips for adding an array to an array of objects with AngularJs

I'm facing an issue with the array structure in my code. Here's what I currently have: $scope.arrayList=[{FirstName:"",LastName:""}]; $scope.Address=[{address:"",PhoneNumber:""}]; What I want to achieve is to push the $scope.Address array into ...

Ways to disseminate arguments when dealing with an array of arrays in JavaScript

Struggling to pass an array as arguments into the join method on path in node, but hitting a roadblock: var path = require("path"); var paths = [__dirname]; var userInput = ["app", "js"]; paths.push(userInput); var target = path.join.apply(null, paths); ...

Guide to streaming audio files using vue.js

I am attempting to incorporate an audio file into my vue.js project using the following code: import sound from '../../recordings/sound.mp4' const audio = new Audio(sound) audio.play() Although this method works perfectly fine, I have encounter ...

How to Maintain Button Activation in NextJS

I am facing an issue with my buttons and form interaction. I have a group of 3 buttons and a form. When I select a button, it stays active as expected. However, once I click on the "submit" button in the form, the previously selected button loses its activ ...

Ways to insert user data into a hidden input field

I am facing an issue with the input field on my website. Users can enter their desired input, and this data is copied into a hidden input field. However, the problem arises when new data replaces the old data. This is where I copy all the data: $('# ...

Transferring user inputs to the server through jQuery-AJAX

I've encountered some issues when trying to send form data inputs to the server. Despite alerting each form input, I keep getting empty alerts. Here's my code snippet: With my current code, it only alerts 0. However, posting normally seems to wor ...

Displaying hidden Divs in React Typescript that are currently not visible

I have an array with various titles ranging from Title1 to Title8. When these titles are not empty, I am able to display their corresponding information successfully. Now, my goal is to include a button that will allow me to show all fields. For example, ...

Methods for concealing a single item in a Vue web form

I am a beginner with Vue and I am facing a challenge in hiding a specific element within a web form that is part of a loop. I am trying to use v-if along with a showHideEditComponent method call. However, when I invoke the showHideEditComponent method wi ...

What could be causing the function to not work properly within the React component?

Having trouble with a React component utilizing speech recognition for converting speech to text. Initialized the recognition functions within the component but encountering errors. Need assistance in troubleshooting this issue. const speechRecognition = w ...

Issues with jQuery slide operation

I'm facing an issue with jQuery and I can't figure out where it's coming from. Here is the error message that keeps showing up in the console: Uncaught TypeError: Object [object Object] has no method 'getElement' script_16.js:46Un ...