inertiajs / inertia

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.
https://inertiajs.com
MIT License
6.23k stars 420 forks source link

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

Closed EmilMoe closed 1 year ago

EmilMoe commented 3 years ago

Versions:

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 commented 3 years ago

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.

grantholle commented 3 years ago

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.

foreverheavy commented 2 years ago

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

claudiodekker commented 2 years ago

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!

ryanhungate commented 2 years ago

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. :)

jcfrane commented 2 years ago

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

mattkingshott commented 2 years ago

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).

simonj commented 2 years ago

I had the same issue. I fixed it by adding

onMounted(() => {
  JSON.parse(JSON.stringify(this.yourDATA))
})
rajan-parmar commented 2 years ago

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).

brunoleles commented 2 years ago

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.

ericmp33 commented 1 year ago

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)))
Atif-Bashir-1998 commented 1 year ago

Instead of doing anything with the props directly, create new variables and reference the props using those.

Cause of the issue:

<script setup>

const props = defineProps({
    foo: String
});

props.foo = "new value";

</script>

In order to fix it I did the following:

<script setup>

const props = defineProps({
    foo: String
});

const myFoo = ref(props.foo);

</script>
tirta-keniten commented 1 year ago

I had the same issue, and this is how I fix it.

const props = defineProps({
    transaction: Object,
    customer: Object,
});

const propsClone = JSON.parse(JSON.stringify(props));

const form = useForm({ transaction:  propsClone.transaction });
reinink commented 1 year ago

Hey! Thanks so much for your interest in Inertia.js and for sharing this issue/suggestion.

In an attempt to get on top of the issues and pull requests on this project I am going through all the older issues and PRs and closing them, as there's a decent chance that they have since been resolved or are simply not relevant any longer. My hope is that with a "clean slate" me and the other project maintainers will be able to better keep on top of issues and PRs moving forward.

Of course there's a chance that this issue is still relevant, and if that's the case feel free to simply submit a new issue. The only thing I ask is that you please include a super minimal reproduction of the issue as a Git repo. This makes it much easier for us to reproduce things on our end and ultimately fix it.

Really not trying to be dismissive here, I just need to find a way to get this project back into a state that I am able to maintain it. Hope that makes sense! ❤️