How does phoenix liveview parses form params? If for example I have a FormData right here:
{_method: "put", _csrf_token: "AEY...", invoice[expenses][0][id]: "185..", invoice[expenses][0][delete]: "false", invoice[expenses][0][product_type_id]: "98e...", …}
which is logged from:
const formData = new FormData(form);
var object: any = {};
formData.forEach(function(value: any, key: any){
object[key] = value;
});
how come in the handle event params it is already formatted and nested into something like this
%{"_method" => "put", "_csrf_token" => "AEY...", "invoice" => %{"expenses" => %{"0" => %{"id" => "185...", "delete" => "false", "product_type_id" => "98e...", ...}}}}
The reason I asked is I might need to use whatever used as parser here to manually pass params to a custom event in my liveview. For example, when select2 changed, I want to pass the full params to validate event just like any other inputs.
Thanks in advance.
Answering my own question
Not totally sure about the flow, I may skip some necessary steps but hopefully, you get the idea.
Form submission or change is handled first by a javascript event handler. During which the FormData is serialize into a URL encoded string via this code right here:
let serializeForm = (form, meta = {}) => {
let formData = new FormData(form)
let toRemove = []
formData.forEach((val, key, index) => {
if(val instanceof File){ toRemove.push(key) }
})
// Cleanup after building fileData
toRemove.forEach(key => formData.delete(key))
let params = new URLSearchParams()
for(let [key, val] of formData.entries()){ params.append(key, val) }
for(let metaKey in meta){ params.append(metaKey, meta[metaKey]) }
return params.toString()
}
The above code is also where _target
is being inserted via meta argument.
The URL encoded string is sent to the LiveView channel and received via the handle_info/2
callback wherein it decodes the URL encoded string to a map using Plug.Conn.Query.decode/1
then eventually send it to the handle_event/3
result handler.
2 Likes