inertia icon indicating copy to clipboard operation
inertia copied to clipboard

Failed to execute 'replaceState' on 'History': #<Object> with Sortable.js

Open EmilMoe opened this issue 2 years ago • 11 comments

Versions:

  • vue version 3.0.5
  • @inertiajs/inertia version 0.9.0
  • @inertiajs/inertia-vue3 version 0.4.0

Describe the problem:

Similar to here, I have this problem when using Sortable.js / VueDraggable: https://github.com/inertiajs/inertia/issues/730

app.js?id=f8cbfda01b9810c19e0f:2 DOMException: Failed to execute 'replaceState' on 'History': #<Object> could not be cloned.
    at e.n.replaceState (/js/app.js?id=f8cbfda01b9810c19e0f:2:28191)
    at e.n.saveScrollPositions (/js/app.js?id=f8cbfda01b9810c19e0f:2:21087)
    at e.n.visit (/js/app.js?id=f8cbfda01b9810c19e0f:2:25155)
    at onClick (/js/app.js?id=f8cbfda01b9810c19e0f:2:11402)
    at At (/js/app.js?id=f8cbfda01b9810c19e0f:2:657430)
    at Pt (/js/app.js?id=f8cbfda01b9810c19e0f:2:657508)
    at HTMLAnchorElement.n (/js/app.js?id=f8cbfda01b9810c19e0f:2:708099)

Steps to reproduce:

Sort elements with sortable.js or Vue draggable and click on any Inertia link.

Similar to the linked thread, I can fix it by modifying the minified javascript file with this:

n.replaceState=function(e){this.page=e,e=JSON.parse(JSON.stringify(e)),window.history.replaceState(e,"",e.url)}

EmilMoe avatar Aug 09 '21 16:08 EmilMoe

It seems that I solved it by copying the list I'm sorting to a data() variable in the Vue component instead of sorting it on a property on the object.

This would fail when sorting `type.list:

data() {
  return {
    type: { prop1: 'string', list: [1,2,3] }
  }
}

This seems not to fail when sorting list:

data() {
  return {
    type: { prop1: 'string', list: [1,2,3] },
    list: []
  }
},
mounted() {
  this.list = this.type.list
}

I'm keeping this open for a while to allow anyone with their comments.

EmilMoe avatar Aug 10 '21 14:08 EmilMoe

After lots of work, I've found out that if you try to modify a prop directly in a component, it will cause this error. This tripped me up with object references (oh javascript). Cloning the prop I needed to do work on solved me issues.

grantholle avatar Aug 24 '21 03:08 grantholle

Just to piggyback on this, I also encountered this issue when using vue.draggable.next (SortableJS) and useForm. Any time I sorted an array property in the form data, this error would occur. I was ultimately able to solve this by unsetting v-model on the draggable component and using the list prop instead. Don't forget to remove the v-model attribute when using list

I still cannot identify the reason using v-model on the component causes this issue, but it ultimately wasn't a bug in Inertia

foreverheavy avatar Nov 03 '21 04:11 foreverheavy

Yeah, so, this is indeed likely related to third-party javascript libraries or user-code creating references, proxy objects, or other 'fancy' rich states that aren't serializable to a JSON string, which then causes this failure.

If someone knows of a way that this can be done (it probably means just ignoring those properties, or some of their child properties / partially serializing those objects?) then please do let me know so we can solve this. If not, I'll probably eventually end up looking for a way that we can tell the user about what's going on with a more friendly console.error message.

Thanks!

claudiodekker avatar Dec 03 '21 09:12 claudiodekker

Just throwing it out there - I had this same problem today and ended up tying it to the "dynamic component" node type. As soon as I removed that from the equation everything worked fine. I have no clue what was causing this but it's annoying. :)

ryanhungate avatar Jan 27 '22 21:01 ryanhungate

I also experienced this when using dynamic components or v-if. Still can't figure out what's wrong.

jcfrane avatar Jan 29 '22 12:01 jcfrane

For anyone experiencing this, I can confirm (at least for me) that it was triggered by directly manipulating a complex prop (e.g. array of objects), on the Inertia page component. The simplest solution is to assign the prop to a variable on the data() method .e.g

data() { return {
    custom_key : this.$page.props.complex_array_of_objects,
}}

And then only modify custom_key from that point forward (basically act as though its the only source of truth).

mattkingshott avatar Mar 28 '22 16:03 mattkingshott

I had the same issue. I fixed it by adding

onMounted(() => {
  JSON.parse(JSON.stringify(this.yourDATA))
})

simonj avatar Mar 31 '22 13:03 simonj

I had the same issue. I fixed it by adding

onMounted(() => {
  JSON.parse(JSON.stringify(this.yourDATA))
})

@SimonJ I have similar issue while i changing the property of array(multi select option where add/remove).

rajan-parmar avatar Apr 19 '22 11:04 rajan-parmar

I had the same issue. I fixed it by adding

onMounted(() => {
  JSON.parse(JSON.stringify(this.yourDATA))
})

Indeed I'd the issue using an object with nested levels of v-models, and this worked, to dissociate the models from the props.

brunoleles avatar Jul 08 '22 02:07 brunoleles

Having same issue! I also fixed it using the "JSON parse JSON stringify" way:

const item = ref(props.item)

to

const item = ref(JSON.parse(JSON.stringify(props.item)))

ericmp33 avatar Oct 10 '22 11:10 ericmp33