Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

491
Views
Which method of adding an element to the array property of a Vuex state property correct?

So I have an action that makes a POST request to an endpoint that creates a comment for a particular artwork. On the components which renders the artwork and its comments, I dispatch an action in the onMounted() hook that makes a GET request for the artwork with that id, and then stores it in the Vuex.

Once the POST request that creates the comment goes through, I can access the artwork property in the store, and just push the response to the comments property which is an array of comments. I don't know if this is the correct way to do it though, since from what I understand any state change should be done through mutations, so directly accessing the state and pushing array elements into it seems incorrect?

This is my action that creates a comment and pushes the response to the selected artwork's comments property:

    async createComment({commit, state}, payload){
        try {
            let response = await axios.post("/createComment", payload)
            console.log(response)
            state.image.comments.push(response.data.comment)
        } catch (error) {
            console.log(error)
        }
    },

I guess the alternative is to copy the artwork from the state, push the new comment in the comments property of the copy, and then commit the new object?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

You can create mutation:

const mutations = {
  addComment(state, comment) {
    state.image = { 
      ...state.image,
      comments: [ ...state.image.comments, comment]
    }
  },
},

and then commit from your action:

async createComment({commit, state}, payload){
    try {
        let response = await axios.post("/createComment", payload)
        console.log(response)
        commit('addComment', response.data.comment);
    } catch (error) {
        console.log(error)
    }
},
over 4 years ago · Santiago Trujillo Report

0

Getting an object from the state and mutating its properties violates the principle of "one source of truth" for all changes, which is why you're using a store in the first place.
You have to replace the object in the state with a modified version of itself. Here's how a mutation might look like, in your case:

this.$store.commit('ADD_COMMENT', comment);
// in store:
mutations: {
  ADD_COMMENT(state, comment) {
    state.image = { 
      ...state.image,
      comments: [ ...(state.image.comments || []), comment]
    }
  }
}

This can also be achieved by push-ing the comment into the existing comments array. But you still have to replace state.image:

// ❌ WRONG, you're not replacing the image:
state.image.comments.push(coment);

// ✅ CORRECT, you're replacing the image:
const clone = { ...state.image };
clone.comments.push(comment);
state.image = clone;

// that's why most prefer the spread syntax, 
// to assign in one line, without using a const: 
// state.image = { ...state.image, [yourKey]: yourNewValue };

Important: mutating state should only happen inside mutation functions. If it happens outside, Vue will warn you. Sometimes it might work (as in, you might actually see the change in the component and it might render correctly), but it's not guaranteed to work.


Example updating an object in a state array:

If the image would be part of an array stored into state, (say images) and considering each image would have an unique identifier id, here's how you could do it:

this.$store.commit('ADD_IMAGE_COMMENT', { id: image.id, comment });

// the mutation:
mutations: {
  ADD_IMAGE_COMMENT(state, { id, comment }) {
    const index = state.images.findIndex(image => image.id === id);
    if (index > -1) {
      state.images.splice(index, 1, { 
        ...state.images[index],
        comments: [...(state.images[index].comments || []), comment]
      });
    }
  }
}

The above mutation mutates the images array in place, effectively replacing it with a new copy of itself, which contains all the other images unmodified and a new version of the modified image at the same index as the old one. The modified image contains everything the old one contained, except the comments array, replaced by a new array, containing everything the old one had, plus the new comment.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!