Troubleshooting tip: Vue and Vuex - computed property will not update upon state change

I'm relatively new to Vue and Vuex, so please bear with me as I navigate through.

My goal is to trigger the computed function versions() whenever there's a change in state.template, specifically when state.template.versions changes.

This section of the component should be re-rendered upon a change in state.template.versions. Here you can find the computed property versions() that should be invoked:

    <el-dropdown-menu class="el-dropdown-menu--wide"
      slot="dropdown">
      <div v-for="version in versions"
        :key="version.id">
           ...
      </div>
    </el-dropdown-menu>
    ...
    computed: {
      ...mapState('documents', ['template', 'activeVersion']),
      ...mapGetters('documents', ['documentVersions', 'documentVersionById', 'documentFirstVersion']),
    versions () {
       return this.documentVersions.map(function (version) {
          const v = {
            id: version.id,
            name: 'Draft Version',
            effectiveDate: '',
            status: 'Draft version',
          }
          return v
        })
    },

Here is the getter:

  documentVersions (state) {
    return state.template ? state.template.versions : []
  },

And here is the action:

  createProductionVersion (context, data) {
    return new Promise((resolve, reject) => {
      documentsService.createProductionVersion(data).then(result => {
        context.state.template.versions.push(data)  // <-- I'm updating state.template here. Expecting versions() to run
        context.commit('template', context.state.template)

        resolve(result)
      })

Lastly, this is the mutation:

  template (state, template) {
    state.template = template
  },

I've come across instances where Vue doesn't detect array changes, yet it seems like .push() operation is being recognized. Source: https://v2.vuejs.org/v2/guide/list.html#Caveats

Any thoughts on why the computed property isn't triggered upon updating context.state.template.versions?

Answer №1

An issue may be arising from the line of code state.template = template. It appears you were correct in identifying it as a reactivity issue, however, it is not related to Array reactivity but rather the template object itself.

Vue lacks the ability to automatically detect property additions or deletions. This includes assigning a complex object to a property. To address this, you should utilize Vue.set.

Therefore, your mutation should be adjusted as follows:

template (state, template) {
  Vue.set(state, "template", template)
},

For more information on this topic, visit: https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats

Answer №2

Your function may not be triggered because of the following mistake:

context.state.template.versions.push(data) 
context.commit('template', context.state.template)

The context.state object only refers to your current state and nothing beyond that.

A recommended solution would be:

  1. To begin with, ensure you declare your store state correctly:

    state: {
       template: {
          versions: []
       }
    }
    
  2. Update your getter without unnecessary conditions:

    documentVersions: state => return state.template.versions,

  3. Add a new mutation:

    ADD_VERSION: (state, version) => {
       state.template = {
         ...state.template,
         versions: [...state.template.versions, version]
        };
      }
    
  4. Adjust your action accordingly:

    createProductionVersion({commit}, data) {
           return new Promise((resolve, reject) => {
             documentsService.createProductionVersion(data).then(result => {
               commit('ADD_VERSION', data);
               resolve(result);
             });
           });
         }
    
  5. In your component, consider updating your computed property from a function to an object containing get and set methods (set is optional):

    versions: {
      get() {
        return this.documentVersions.map(function (version) {
          const v = {
            id: version.id,
            name: 'Draft Version',
            effectiveDate: '',
            status: 'Draft version',
          }
          return v
        })
      }
    },
    

Answer №3

The reason for this issue is likely due to your store state not being properly declared. Ensure that you include the versions property within your template object.

state: {
  template: {
    versions: []
  }
}

By doing this, any modifications made to the versions property will be detected by vue.js.

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

Keep sending ajax request until the page is closed

Is it possible to resend an ajax request continuously using pure javascript without any framework? Here is an example of how I am currently attempting to do it: xmlhttp=new XMLHttpRequest(); xmlhttp.open("POST","demo_post2.asp",true); xmlhttp.setRequest ...

Retrieving the value of an array from a JSON data structure

I am working with the object shown below to extract the desired output. The result will be a new object that represents the final output. var data = { Customer: { Name: "emp1", Departments: [ {Departme ...

Struggling with a character entity in Javascript? Learn how to escape it and avoid any display issues (such as showing

document.title = ("welcome &rarr; farewell"); Trying to display the arrow symbol "→" but it's not showing correctly. Any tips on how to properly escape it? ...

Combining two arrays in React using TypeScript and showcasing them in a single list display

I am working on a React TypeScript project and have two comma-separated strings that I am converting into arrays. One array contains the file names, and the other contains the file link paths. My goal is to merge the two arrays so that the first item in th ...

Transferring data from PHP to JavaScript through JSON

Seeking advice on a unique issue that sets it apart from the rest. I am successfully passing JSON data from PHP to JavaScript using the jQuery.ajax() method, but here's my dilemma: I have contact data in MySQL with fields like firstname, lastname, la ...

Array fed with Mongoose query

Currently experiencing challenges with a section of my code. I am utilizing Mongoose to retrieve data from my database, where I intend to push a portion of that data into an array titled 'authors' for further manipulation. Although I am able to ...

Issue with jQuery ajax in Internet Explorer 6

Hey there, I'm dealing with a strange issue: The success handler in my $.ajax call looks like this: function(data){ alert(data); } Seems pretty straightforward, right? The problem I'm facing is that the data sent by the server is ALW ...

Interpreting Multilayered JSON Objects using JQuery

Hello everyone! I've posted my sample json data below. While I am proficient in PHP, I am relatively new to jQuery. "data":{ "cipher":"true", "size":[ "2.2 Mb", "6.11 Mb", "9.25 Mb", ...

The customer opts to store all images indefinitely into the data stream

I have set up a node server that captures images from a webcam at regular intervals and sends them to the client using the Delivery.js node module. Upon monitoring the browser resources in Chrome development tools, it appears that each image sent is being ...

What is the best way to add an element after a specific child element with jquery?

Is there a way to add a paragraph element after a specific div class element? I am looking to include a p element within the second text div class. I attempted a solution, but it is not producing the desired result. The current solution is not effective. ...

IE9 encounters an error when using jQuery's .remove() function

While testing my website in IE9 using Firebug Lite, I encountered an issue. When attempting to run a basic command to remove a div, I received an error saying "TypeError: Object expected". The command I used was: $("#drag-hoverbox_you").remove(); Interes ...

Implementing a sibling combinator technique within Material UI's useStyles framework

Is there a way to change the background of one div when hovering over another using material ui? The traditional CSS method is: #a:hover ~ #b { background: #ccc; } Here is my attempt with Material UI: const useStyles = makeStyles(theme => ({ ...

Problem encountered with Firefox when using jQuery's hide() function

I am facing an issue with the hide() function in a project I am working on. The selected div layer is not hiding as expected. Everything seems to be functioning correctly in Safari and Chrome, but unfortunately, it is not working in Firefox :-( You can v ...

Verify the dimensions of the file being uploaded

I have a file uploader component that requires a dimensions validator to be added. Below is the code for the validator: export const filesDimensionValidator = (maxWidth: number, maxHeight: number): ValidatorFn => (control: AbstractControl): Vali ...

What is the best way to use a Handlebars file on multiple routes?

I have been working on extracting articles from a news website by scraping them successfully. The data is being displayed properly on the front-end console log, but I am facing an issue with rendering it onto the page using a button - it only appears when ...

What are the various undisclosed schema types in A-Frame?

I've been exploring different examples of property types in the official documentation and various Github repositories (though now I can't remember which ones). The latter introduced me to unique properties like "min" and "max" for numbers, as we ...

Switching from using v-data-table to v-virtual-scroll

I am currently in the process of switching from using v-data-table to v-virtual-scroll, but I am struggling to determine the correct syntax for the virtual scroller. Can you assist me with this, please? I want to maintain the same display as before, but no ...

Learn how to create a "generated" texture coordinate in three.js similar to how it is done in Blender Cycles

How can I properly display a texture on a cylinder object using THREE.js without distortion? Currently, the texture appears stretched along the edges of the cylinder as shown here: https://i.sstatic.net/O2YFr.png This issue is based on the texture provide ...

Eliminate nested object properties using an attribute in JavaScript

I am working with a nested object structured like this const data = [ { id: '1', description: 'desc 1', data : [ { id: '5', description: 'desc', number :1 }, { id: '4', description: 'descip& ...

Exploring the JSON Structure in NodeJS

My current json array is structured in the following way: [{"id": 1, "meeting": "1/3/2015 12:30:00 PM", "name": "John"}, {"id": 1, "meeting": "1/3/2015 13:30:00 PM"}, "name": "John"}, {"id": 2, "meeting": "1/5/2015 7:00:00 AM"}, "name": "Peter"}, {"id": 2 ...