bigskysoftware / htmx

</> htmx - high power tools for HTML
https://htmx.org
Other
37.69k stars 1.27k forks source link

[version 2.0.0-beta1] formData instead of parameters in htmx event #2616

Closed LucaPanofsky closed 2 months ago

LucaPanofsky commented 3 months ago

Hello, in the new beta there seems to be a breaking change in the way the event is handling parameters.

In the current latest the htmx event has the property parameters that is a JS object. Now the htmx event seems to work with formData.

This behavior is not described here https://v2-0v2-0.htmx.org/migration-guide-htmx-1/

My question is, is that intended or not? If it is, there will be a way to preserve the current behavior?

Telroshan commented 3 months ago

Hey, we implemented the internal FormData change with a proxy object, so you should be able to use it just as you were before, as direct assignments (like an object's entries) will be handled by the proxy. Let us know if it doesn't work as expected though!

PS: Along the parameters and unfilteredParameters properties that use this proxy for retro-compatibility, please note we also added formData and unfilteredFormData that are the actual FormData object, i.e. not the proxy one.

LucaPanofsky commented 3 months ago

The main issue is that now complex objects are parsed as [Object object] breaking the app when switching to the beta, is there a way to restore the old behavior?

Telroshan commented 3 months ago

Sounds like an issue we'd want to fix indeed! For now if you need the old behavior you may just not upgrade to htmx 2, though feel free to open a bugfix PR for this, it's definitely an issue that objects aren't serialized as they did before.

LucaPanofsky commented 3 months ago

Not sure I am looking at the right place,

https://github.com/bigskysoftware/htmx/blob/ec63577ec331cb7351e28404d7eff05c196ae3dd/src/htmx.js#L2218

function makeFormData(values) {
            var formData = new FormData();
            for (var name in values) {
                if (values.hasOwnProperty(name)) {
                    var value = values[name];
                    if (Array.isArray(value)) {
                        forEach(value, function(v) {
                            formData.append(name, v);
                        });
                    } else {
                        formData.append(name, value);
                    }
                }
            }
            return formData;
        }

It seems to me that that is impossible to include a JS object as a value, only strings. Hence, if my understanding is correct, the only possibility would be to parse the object into a JSON but this would not fix compatibility with current version

Telroshan commented 3 months ago

How did a request payload look like in the network tab with the 1.x version in this situation? Was the object rendered as a JSON string or was it handled otherwise?

LucaPanofsky commented 3 months ago

Parameters were constructed through include-vals, there I create some JS objects (no need to use include-vals, can hook into relevant events).

Going to provide reproducible code in the following days

The paylod was a well formatted json (using json-enc)

LucaPanofsky commented 3 months ago

version 2 breaks Schermata da 2024-06-18 22-44-13 Schermata da 2024-06-18 22-46-41 Same result without json-enc Schermata da 2024-06-18 23-01-15

version 1.x.x ok Schermata da 2024-06-18 22-49-40 Schermata da 2024-06-18 22-49-23

karolskolasinski commented 1 month ago

where is my form data? It is not under formData or under parameters

image

const preventSubmitIfNoChange = {
    ["hx-on:htmx:before-request"]: `
      console.log(event);
      return;
    `,
  };