AE
Ash Elixir•3y ago
Blibs

Manually adding argument to action in form before calling AshPhoenix.Form.submit

I'm using AshPhoenix.Form to handle creation of a resource in LIveView. In my resource, I added this action:
create :my_create do
argument :images, {:array, :map}, allow_nil?: false

change fn changeset, %{actor: actor} ->
Ash.Changeset.after_action(changeset, fn changeset ->
...
changeset
end)
end
end
create :my_create do
argument :images, {:array, :map}, allow_nil?: false

change fn changeset, %{actor: actor} ->
Ash.Changeset.after_action(changeset, fn changeset ->
...
changeset
end)
end
end
That action now needs to receive a list of images which is a list of maps. That list is created during the "submit" event after I consume images uploaded:
images =
consume_uploaded_entries(socket, :images, fn %{path: path}, entry ->
data = File.read!(path)

{:ok, %{data: data, client_type: entry.client_type, uuid: entry.uuid}}
end)

...
# Want to add images to the form as an argument here

case AshPhoenix.Form.submit(form) do
...
images =
consume_uploaded_entries(socket, :images, fn %{path: path}, entry ->
data = File.read!(path)

{:ok, %{data: data, client_type: entry.client_type, uuid: entry.uuid}}
end)

...
# Want to add images to the form as an argument here

case AshPhoenix.Form.submit(form) do
...
So, what I need now is to add the images variable as the :images argument of my :my_create action to my form before calling AshPhoenix.Form.submit. Is there a way to do that?
7 Replies
ZachDaniel
ZachDaniel•3y ago
AshPhoenix.Form.for_create(...., prepare_source: fn changeset ->
Ash.Changeset.set_argument(changeset, :argument_name, :value)
end)
AshPhoenix.Form.for_create(...., prepare_source: fn changeset ->
Ash.Changeset.set_argument(changeset, :argument_name, :value)
end)
And then if you want to do it on submit (because that is when you have the images)
form
|> AshPhoenix.Form.update_options(prepare_source: fn changeset ->
...
end)
|> AshPhoenix.Form.submit(...)
form
|> AshPhoenix.Form.update_options(prepare_source: fn changeset ->
...
end)
|> AshPhoenix.Form.submit(...)
Blibs
BlibsOP•3y ago
update_options seem to expect a function, not a keyword 🤔
ZachDaniel
ZachDaniel•3y ago
oh, sorry merge_options
Blibs
BlibsOP•3y ago
Hmm, after calling merge_options the field prepare_source is still nil, I believe it should have that function now right?
ZachDaniel
ZachDaniel•3y ago
🤔 right you are Sorry about that, for now just do this
form
|> Map.put(:prepare_source, fn changeset ->
...
end)
|> submit()
form
|> Map.put(:prepare_source, fn changeset ->
...
end)
|> submit()
Blibs
BlibsOP•3y ago
Hmm, submit is still returning an error saying that :images is required for some reason 🤔 I don't know why, but this worked if I add both when creating the form and when submitting:
form = AshPhoenix.Form.for_create(Markets.Property, :my_create,
api: Markets,
actor: actor,
prepare_source: fn changeset ->
Ash.Changeset.set_argument(changeset, :images, [])
end)
form = AshPhoenix.Form.for_create(Markets.Property, :my_create,
api: Markets,
actor: actor,
prepare_source: fn changeset ->
Ash.Changeset.set_argument(changeset, :images, [])
end)
changeset_fn = fn changeset ->
Ash.Changeset.set_argument(changeset, :images, images)
end

form = %{form | prepare_source: changeset_fn}

case AshPhoenix.Form.submit(form) do
changeset_fn = fn changeset ->
Ash.Changeset.set_argument(changeset, :images, images)
end

form = %{form | prepare_source: changeset_fn}

case AshPhoenix.Form.submit(form) do
ZachDaniel
ZachDaniel•3y ago
Yeah, this makes sense, although its not ideal. The reason you need both is likely because images is a required argument and so the initial form validation isn't valid without it

Did you find this page helpful?