Inertia: Page replaceState issue with Proxy Vue 3

Created on 29 Oct 2020  路  7Comments  路  Source: inertiajs/inertia

Current receiving an issue with trying to use Laravel Jetstream's Inertia Form:

Uncaught DOMException: Failed to execute 'replaceState' on 'History': [object Object] could not be cloned.
    at Proxy.replaceState (http://localhost:3000/js/admin.js:24884:39)
    at Proxy.saveScrollPositions (http://localhost:3000/js/admin.js:24697:14)
    at Proxy.visit (http://localhost:3000/js/admin.js:24798:73)
    at Proxy.put (http://localhost:3000/js/admin.js:24923:73)
    at Proxy.submit (http://localhost:3000/js/admin.js:51142:47)
    at Proxy.put (http://localhost:3000/js/admin.js:51100:25)
    at Proxy.onSubmit (http://localhost:3000/js/admin.js:42751:17)
    at callWithErrorHandling (http://localhost:3000/js/admin.js:31936:22)
    at callWithAsyncErrorHandling (http://localhost:3000/js/admin.js:31945:21)
    at emit (http://localhost:3000/js/admin.js:32390:9)

This seems to be because the page argument that is getting passed to replaceState is actually a proxy since the Jetstream Inertia Form instance is part of the component's data object.

I did see that #297 had been merged to fix similar errors but this one still persists.

Currently using :

@inertiajs/inertia 0.6.1
@inertiajs/inertia-vue3 0.2.1

(the issue existed on previous version as well).

A fix that seems to solve the problem is:

  pushState(page) {
    this.page = page
    const clone = JSON.parse(JSON.stringify(page))
    window.history.pushState(clone, '', page.url)
  },

  replaceState(page) {
    this.page = page
    const clone = JSON.parse(JSON.stringify(page))
    window.history.replaceState(clone, '', page.url)
  },

Happy to make a PR for this but completely understand if you feel the issue is out of scope of since it mainly relates to a different package.

bug investigate vue 2

All 7 comments

Hi,

I'd be happy to take a look at this. What version of jetstream-js do you have installed?
Also, could you show me the violating piece of code, so we can use that to replicate it?

Thanks!

Maybe @m1guelpf can help as well, because he apparently ran into the same issue.

@rwdevguy Could you upgrade jestream-js to v1.1.0 and try again?

@m1guelpf I've updated to v1.1.0, however, I'm using the package globally so it uses the preexisting install method rather than the useForm() hook which you introduced.

I can confirm that using shallowReactive around this.$inertia.form({...}) does seem to fix the issue.

@claudiodekker Here is an example:
app.js

import {createApp, h} from "vue";
import {app, plugin} from "@inertiajs/inertia-vue3";
import {InertiaForm} from "laravel-jetstream";

const el = document.getElementById("app");

createApp({
    render: () =>
        h(app, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: name => require(`@/Pages/${name}`).default,
        }),
})
    .use(plugin)
    .use(InertiaForm)
    .mount(el);

Test.vue

<template>
    <div>
        <button @click="submitWithInertia">
            Submit with Inertia
        </button>
        <br />
        <button @click="submitWithLaravelJetstream">
            Submit with Laravel Jetstream Inertia Form
        </button>
    </div>
</template>

<script>
export default {
    data() {
        return {
            form: this.$inertia.form({
                test: "test",
            }),
        };
    },

    methods: {
        submitWithInertia() {
            this.$inertia.post("/some-endpoint", this.form.data());
        },
        submitWithLaravelJetstream() {
            this.form.post("/some-endpoint");
        },
    },
};
</script>

@rwdevguy This is definitely related to laravel-jetstream then, I'm guessing it'd be best to close here and open there.

@m1guelpf Yeah, I already figured from the first message that this was the case, but it really isn't a huge issue to keep the issue here and to have us look into it, as the plan is for jetstream-js to be consumed into Inertia entirely before 1.0.0 hits anyway 馃憤

Okay, so I'm pretty sure the issue here is local state caching (the "remember" feature). We actually ran into the same problem recently while adding the Jetstream form helper to the Vue 2 and Vue 3 adapters. The issue is that the Jetstream form object cannot be serialized when being saved to the history state (via the remember feature). That's because it's a class, with functions, and not just plain data.

We solved this in our new form helper using new serialize and unserialize methods, that Inertia will automatically check for and call when saving the remember data to history state.

https://github.com/inertiajs/inertia/blob/17e6c711d91d7ab33bd3557b032a8ddcac6b124b/packages/inertia-vue/src/form.js#L59-L68

Meaning, this is a Jetstream issue, but one that we've solved in the latest version of Inertia. All these changes are being brought to Jetstream 2.0. 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adriandmitroca picture adriandmitroca  路  5Comments

TimVanHerwijnen picture TimVanHerwijnen  路  5Comments

philippkuehn picture philippkuehn  路  3Comments

piercemcgeough picture piercemcgeough  路  4Comments

ninjaparade picture ninjaparade  路  4Comments