`update_form` doesn't update params on root form

Im using the AshPhoenix.Form.update_form function to update a subform of the root form. If after the update_form I call a validate or update_params on the root form the params are reset to the values before the update_form call. Since a code snippet says more than 1000 words:
# Create form and add author sub-form with default value for email
form =
AshPhoenix.Form.for_create(Post, :create, forms: [auto?: true])
|> AshPhoenix.Form.add_form(:author,
params: %{
"email" => "example@email.org"
}
)

# Use update form to update the email of the author
form =
AshPhoenix.Form.update_form(form, :author, fn author_form ->
AshPhoenix.Form.update_params(author_form, fn params ->
Map.put(params, "email", "changed@email.org")
end)
end)

assert AshPhoenix.Form.get_form(form, [:author]) |> AshPhoenix.Form.value(:email) == "changed@email.org"

# Now update some other attributes on the root form
form =
AshPhoenix.Form.update_params(form, fn params ->
Map.put(params, "text", "text value")
end, only_touched?: true, target: ["text"])

# This fails
assert AshPhoenix.Form.get_form(form, [:author]) |> AshPhoenix.Form.value(:email) == "changed@email.org"
# Create form and add author sub-form with default value for email
form =
AshPhoenix.Form.for_create(Post, :create, forms: [auto?: true])
|> AshPhoenix.Form.add_form(:author,
params: %{
"email" => "example@email.org"
}
)

# Use update form to update the email of the author
form =
AshPhoenix.Form.update_form(form, :author, fn author_form ->
AshPhoenix.Form.update_params(author_form, fn params ->
Map.put(params, "email", "changed@email.org")
end)
end)

assert AshPhoenix.Form.get_form(form, [:author]) |> AshPhoenix.Form.value(:email) == "changed@email.org"

# Now update some other attributes on the root form
form =
AshPhoenix.Form.update_params(form, fn params ->
Map.put(params, "text", "text value")
end, only_touched?: true, target: ["text"])

# This fails
assert AshPhoenix.Form.get_form(form, [:author]) |> AshPhoenix.Form.value(:email) == "changed@email.org"
I'm wondering whether this is a bug or if there's something I'm missing in the usage of update_form.
6 Replies
sevenseacat
sevenseacat2mo ago
so what is the value then, if not changed@email.org? I suspect something around only_touched? - what happens if you remove that?
Rutgerdj
RutgerdjOP2mo ago
Its example@email.org (set as the default when adding the form) Removing only_touched? doesnt change anything I mean it makes sense that the update_params overrides the values set by the update_form given that the update_form doesnt change the params on the root form I've found this thread: https://www.answeroverflow.com/m/1396883753443524788#solution-1396886969719459984 Which suggests validating again with params from the params function:
form = AshPhoenix.Form.validate(form, AshPhoenix.Form.params(form))
form = AshPhoenix.Form.validate(form, AshPhoenix.Form.params(form))
Which seems to work. But then I run into new issues where the params cannot be cast into the correct type. For example When you have a Union type in a form its params value is a struct (%Ash.Union{}) The value in the raw_params is %{"value" => "value", "_union_type" => "type"} which could be cast into the params
sevenseacat
sevenseacat2mo ago
I thought I'd done something similar like this in the past - I didn't use update_params, I had code like
updated_form =
AshPhoenix.Form.update_form(form, form_path, fn form ->
updated_params = Map.put(AshPhoenix.Form.params(form), field_name, value)
Form.validate(form, updated_params)
end)
updated_form =
AshPhoenix.Form.update_form(form, form_path, fn form ->
updated_params = Map.put(AshPhoenix.Form.params(form), field_name, value)
Form.validate(form, updated_params)
end)
Rutgerdj
RutgerdjOP2mo ago
Don't think it matters what you do to the form in the update_form. It just doesnt update the params on the root form.
sevenseacat
sevenseacat2mo ago
well no, because you're updating the nested form, not the root form
ZachDaniel
ZachDaniel2mo ago
Correct, it just doesn't update the params. There is update_params if you want to update the params

Did you find this page helpful?