Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vuex commit : JSON circular structure error

I am using Vue.js with the vuex store. I call an API method to validate an item, the method returns an array of errors and an array of warnings.

My vuex action :

export function validateitemReview ({ commit, dispatch, state }, { reviewId, type, itemreviewData }) {
  console.log('*** validateItemReview() called')
  return api.post(`/clients/districts/reviews/${reviewId}/${type}/validate`, itemreviewData).then(response => {
    console.log('response.data :')
    console.log(response.data)
    commit('setItemReviewsErrors', 'teststring')
  })
}

As you can see, i'm not doing much with the response yet. The called setItemReviewsErrors mutation in the vuex store :

export const setItemReviewsErrors = (state, data) => {
  console.log('*** setItemReviewsErrors() called, data:')
  console.log(data)
}

Here comes my problem, my console output is the following :

*** validateItemReview() called
response.data :
{
    fatal_errors: []
    warnings: []
    __proto__: Object
}
*** setItemReviewsErrors() called, data:
teststring

directly followed by this error :

Uncaught (in promise) TypeError: Converting circular structure to JSON
    at JSON.stringify (<anonymous>)
    at eval (vuex-persistedstate.es.js?0e44:1)
    at eval (vuex-persistedstate.es.js?0e44:1)
    at eval (vuex.esm.js?2f62:392)
    at Array.forEach (<anonymous>)
    at Store.commit (vuex.esm.js?2f62:392)
    at Store.boundCommit [as commit] (vuex.esm.js?2f62:335)
    at local.commit (vuex.esm.js?2f62:651)
    at eval (itemreview_actions.js?0d87:62)

itemreview_actions.js?0d87:62 is the following line in my vuex validateitemReview() action:

commit('setItemReviewsErrors', 'teststring')

if I comment it, no more error. I can't figure where could be my "circular structure" when the problems seems to come from committing a simple string.

Even better, why:

  • my console.log() from the setItemReviewsErrors mutation is still printed and the error comes after even though the error seems to be while calling this method
  • If I reload the page (Ctrl+R in browser), there are no errors but if I leave it (go to another page) and then come back to it, the error is thrown again.

Update

The problem seems to come from the plugin vuex-persistedstate . I found out that the vuex store of this application is using it. I am not alone with this problem :

  • https://github.com/robinvdvleuten/vuex-persistedstate/issues/152

  • https://github.com/robinvdvleuten/vuex-persistedstate/issues/41

But the dev just closes the tickets. If anyone has a lead to solve that, I am not allowed to remove the persistence plugin.

like image 336
Tom Avatar asked Dec 02 '18 10:12

Tom


1 Answers

See this alternate library, vuex-persist, they meet this problem head-on

If you have circular structures in your state

let x = { a: 10 }  
x.x = x  
x.x === x.x.x // true  
x.x.x.a === x.x.x.x.a //true  

JSON.parse() and JSON.stringify() will not work.

You'll need to install circular-json

npm install circular-json

And when constructing the store, add supportCircular flag

new VuexPersistence({
  supportCircular: true,
  ...
})

However, a circular reference in state may cause you other problems, if at some stage a reactive property triggers another call to the same mutation. That said, you would likely see the problem quickly as a Maximum call stack size exceeded error.

See the comment by Linus Borg on this code

mutations:
saveVideoComment(state, {id, text, videoId}) {
    let comment = {
        id: id,
        videoId: videoId,
        text: text,
        inlineUserVideo: state.userVideos[userVideoId]
    };
    Vue.set(state.videoComments, id, comment);
    state.videos[videoId].comments.push(id);
    state.videos[videoId].inlineComments.push(comment);
}
like image 170
Richard Matsen Avatar answered Oct 19 '22 07:10

Richard Matsen