Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FormHelper transform not working #1131

Closed
mrmonat opened this issue Mar 15, 2022 · 24 comments
Closed

FormHelper transform not working #1131

mrmonat opened this issue Mar 15, 2022 · 24 comments
Labels
react Related to the react adapter

Comments

@mrmonat
Copy link

mrmonat commented Mar 15, 2022

Versions:

  • @inertiajs/inertia version: 0.11.0
  • @inertiajs/inertia-react version: 0.8.0

Describe the problem:

The transform function of the form helper does not work.

Steps to reproduce:

const { data, setData, transform, post } = useForm({
        status: 'default',
        foo: 'bar',
    })

function handleDraft(event) {
        event.preventDefault()
        transform(data => ({ ...data, status: 'draft' }))
        post('/test')
 }

function handleSave(event) {
        event.preventDefault()
        transform(data => ({ ...data, status: 'open' }))
        post('/test')
}
Route::post('/test', function (Request $request) {
    return dd($request->all());
});

In both cases (handleSave or handleDraft called) the result from the laravel controller is:

^ array:2 [[▼]()
  "status" => "default"
  "foo" => "bar"
]
@mrmonat mrmonat added the react Related to the react adapter label Mar 15, 2022
@muh-hizbe
Copy link

muh-hizbe commented Apr 1, 2022

+1

i got same problem

@mrmonat
Copy link
Author

mrmonat commented Apr 1, 2022

I tested again with react 18 instead of react 17, but the problem still remains

@muh-hizbe
Copy link

for now i use alternatif way,

const [data, setData, reset] = useForm();
.
.
.
Inertia.post('url', {...data, custom_field: custom_value})

@aviemet
Copy link

aviemet commented Apr 27, 2022

Not sure if this is the same issue, but I'm having similar problems with a Rails backend. I've found that if my server responds with anything other than a success, the transform method doesn't run. This makes debugging incredibly difficult and confusing. I was hoping to be able to throw some values at my server and see what shape they arrived, then make it look the way Rails wants it to look. Instead it seems I have to build my transforms in another method and then move it over to the transform block once it's ready?

To make it even more confusing, console.log doesn't output anything from within the transform method, regardless of server response. Likewise, inspecting form data after running transform doesn't reflect the transformations, so there's no way to view the shape of your data after it's been transformed. The only way I've found is by inspecting the body of the request in the Network tab of dev tools.

It would really be great to have access to the shape of the transformed data client side before it gets sent off to the server, and even greater if the transform was applied to the request regardless of server response.

@reinvanimschoot
Copy link

I just stumbled across the same issue. Is there any update on when this would be fixed?

@den1n
Copy link

den1n commented Oct 14, 2022

Why is the issue not being resolved? It's been eight months!

You have a PR #1171. Why is not merged?

@wamuyu-felix
Copy link

I am facin the same issue with vue3

@Dolaned
Copy link

Dolaned commented Nov 13, 2022

I am facin the same issue with vue3

so am i

@mahangm
Copy link

mahangm commented Dec 8, 2022

Is there no fix for this issue still?

@sbc640964
Copy link

Still not fixed?

@Jamesking56
Copy link

I'm currently facing this issue too

@den1n
Copy link

den1n commented Feb 14, 2023

Issue is still present in v1.0.

@Jamesking56
Copy link

@RSDrsd That works really well thanks, I was getting the validation errors not coming back before but with your workaround the error messages now work!

@jerooomewolf
Copy link

Any update?

@pikapikamart
Copy link

Hope this will be fixed, there's a pr for this

@aviemet
Copy link

aviemet commented May 21, 2023

I thought I might offer a solution for those searching for something quick. I built my form solution to be reusable, and published it to npm to make things easier for me. It includes a re-work of useForm which fixes the transform issue and can be used as a direct drop-in for the original hook. It does a few other things, but if you just need a fix for this issue, it might be of use. You can find it here: https://github.com/aviemet/useInertiaForm

Please feel free to use it, copy it, steal it, improve it, etc.

@pikapikamart
Copy link

pikapikamart commented May 22, 2023

@aviemet Really neat!! Just looked at the repo and it looks really nice. Will try to use it in another project!

@reinink
Copy link
Member

reinink commented Jul 28, 2023

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! ❤️

@Kamleshpaul
Copy link

Any update i m stuck on this issue

@gamboitaygb
Copy link

I had the same problem, so, I just change my focus, I tried
post(url,{ transform:(data)=>({...data,{'field':value}}) })

But din't work, so, how can I do the same using inertia? Using router.visit, so router have shortcut, then I changed post from useForm to

router.post(url,{'field':'value'},{ onSuccess: (page) => { // something here }, })
Something that fucked me was losing the processing variable from useForm though, instead using react setState I got the same effect using setState on onBefore and in onSuccess

@aviemet
Copy link

aviemet commented Mar 12, 2024

Due to the way the bug is introduced, there unfortunately isn't any way to circumvent it and still have the benefits of the useForm methods. My only suggestions are to import of the fixed versions that have come out of this 2 year long bug fix request. One is my own and another was created by a commenter on the open PR fix for this bug.

I created a package which fixes this issue and also adds support for nested form data. If you want to use the nested data solution, or don't mind the slightly larger import size, that could be useful for you.

Another person left a comment that they created a new npm package from a fork of Inertia where the only change is properly memoizing the transform method (which fixes the bug).

@derrickreimer
Copy link
Contributor

Given the current implementation of transform, the key detail here is that your calls to transform need to be located in the body of the component (so it gets called on every render), rather than inside a handler callback (see discussion here #1491 (comment)).

Here's a workaround for the OP:

const { data, setData, transform, post } = useForm({
  status: "default",
  foo: "bar",
});

// Store the current "status" in a ref
const statusRef = useRef("default");

// Place the transform call in the function body
transform((data) => ({ ...data, status: statusRef.current }));

function handleDraft(event) {
  event.preventDefault();
  statusRef.current = "draft";
  post("/test");
}

function handleSave(event) {
  event.preventDefault();
  statusRef.current = "open";
  post("/test");
}

@seanburlington
Copy link

This is the workaround I have come up with for a slightly different use case.

I have articles which may be in draft state - they can always be saved (with the draft state left unchanged)

But I also want buttons to publish or unpublish which should change the draft status and then save

I originally thought I could use transform for this but realised it doesn't work that way.

Instead I added a flag to the "data" object to indicate the status has saved - now I set this flag and change the draft status.

When the component re-renders the flag is detected (set back to false) and the save is triggered - now with the updated "data" object.

I haven't used this in production yet - it works in testing and I'd be interested in whether people thing this is a good approach.

    // 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();
    }

@jspotten
Copy link

jspotten commented Dec 7, 2024

This is still not resolved. I am using a Laravel Vue setup and no matter what I've tried, form.transform is never triggered when calling regular or arrow functions. Like others have mentioned, you can't log inside of the callback function to see if it is ever entered. Would be nice for this to be addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
react Related to the react adapter
Projects
None yet
Development

Successfully merging a pull request may close this issue.