Hi guys i have this form that has 2 file_input. one for photo another for signature. but am finding it difficult to write my logic to upload the 2 field at a time. the logic i have works for photo works well. please i need your help .
here is my code
def create(conn, %{"identification_document" => identification_document_params}) do
if upload = (identification_document_params["photo"]) do
fpth = upload_file(upload)
identification_document_params =
Map.merge(identification_document_params, %{"photo" => fpth})
case ScholarshipFormTwo.create_identification_document(identification_document_params) do
{:ok, identification_document} ->
conn
|> put_flash(:info, "Identification document created successfully.")
|> redirect(to: Routes.identification_document_path(conn, :show, identification_document))
{:error, %Ecto.Changeset{} = changeset} ->
delete_old_file(fpth)
changeset |> IO.inspect()
Enum.into(identification_document_params, %{"photo" => nil})
render(conn, "new.html", changeset: changeset)
end
end
end
First, I’m not entirely sure that it would be a good idea to wrap your entire action in that if upload..., because if it is indeed a required parameter, it would be much better to let ecto validate it and return some useful error to the user.
As to how you would upload multiple files, observe that the code from the if statement to the case statement ‘takes’ a map and returns a map, so you could simply chain a similar code and get the desired output, or simply repeat it eg :
identifiaction_params = case identification_params["photo"] do
nil -> identification_params
upload -> fpth = upload_file(upload)
identification_params |> Map.merge(%{"photo" => fpth})
# and then the same thing for "signature"
You could wrap this logic in a function that takes a map and a string and returns a map and then simply pipe the params map through a chain of functions.
Note that there are some issues that are not handled here : what happens if upload_file fails ?
malformed request, a UndefinedFunctionError exception was raised with message “function :raw_file_io_delayed.open_layer/3 is undefined (module :raw_file_io_delayed is not available)”
looks like i got it fixed. well i don’t know if its the best way. i just did nested if (if condition inside another if).
thanks again Krstfk. although a better solution will not be taken for granted.