Tangible Bytes

A Web Developer’s Blog

Inertiajs Transform Workaround

InertiaJs does a great job of helping me build React apps on Laravel. The form help does a great job - especially with displaying validation messages.

But I couldn’t figure out how to change data and save the form in one action.

What I want to do

I have a site with articles which may be in a draft state and wanted to offer the user two options

One button to save the article

One button to change the draft status and then save the article

Inertia’s Transform helper

Inertia’s useForm helper has a transform method - which looks great

If you need to modify the form data before it’s sent to the server, you can do so via the transform() method.

https://inertiajs.com/forms#form-helper

But it turns out this can’t be used in a handler

There are quite a few github issues regarding this

See in particular

I’ve been looking into this one and believe I arrived at the crux of the confusion. The transform function is designed to be called in the body of the component, not inside a handler function.

transform method in useForm hook doesn’t work #1631

My Workaround

I avoid submitting the form in the handler and instead the handler changes the data and sets a flag.

When React renders my component the render checks for this flag and if found it resets the flag, then posts my form (which by now has the updated data).

I’m still not 100% sure this is optimal but it seems to work OK for me so far.

Here is my code.

// change draft state and trigger a save 
const publish = () => {
    setData({ ...data, changedPublishedState: true, "draft": false });
}
const unpublish = () => {
    setData({ ...data, changedPublishedState: true, "draft": true });
}
// save without changing state 
const submit = (e) => {
    e.preventDefault();
    save();
}

const save = () => {
    post(route("article.update", { site: site.id, article: article.id }),
        {
            preserveScroll: false,
            preserveState: (page) => Object.keys(page.props.errors).length,
            onSuccess: () => {
                setTab("edit");
            }
        });
};
// triggered after a re-render when data.draft status has been changed
if (data.changedPublishedState) {
    setData("changedPublishedState", false);
    save();
}