Cant get upload from frontend to work with Ecto 3 and arc_ecto in Phoenix API.
Okay, I'm trying to use this library with Phoenix 1.4 and all things updated (looking to you Ecto v3.). I have already in the past used this library just fine to get my React frontend sending uploads to arc.
But now the things seems to change a lot and I'm getting errors that seems related to cast_attachments not doing its things correctly.
This is the error in the console:
[info] POST /api/v1/customers
[debug] Simple CORS request from Origin "http://localhost:8080" is allowed
[debug] QUERY OK source="users" db=1.1ms queue=0.6ms
SELECT u0."id", u0."username", u0."email", u0."password_hash", u0."inserted_at", u0."updated_at" FROM "users" AS u0 WHERE (u0."id" = $1) [1]
[debug] Processing with ApiWeb.Store.CustomerController.create/2
Parameters: %{"customer" => %{"avatar" => %{"filename" => "3x4.jpg", "path" => "uploads/customers/avatar/"}, "cpf" => "96416076268", "email" => "null", "name" => "Aislan", "phone" => "89999762292"}}
Pipelines: [:api, :jwt_authenticated]
[info] Sent 500 in 86ms
[error] #PID<0.691.0> running ApiWeb.Endpoint (connection #PID<0.674.0>, stream id 5) terminated
Server: localhost:4000 (http)
Request: POST /api/v1/customers
** (exit) an exception was raised:
** (FunctionClauseError) no function clause matching in Arc.File.new/1
(arc) lib/arc/file.ex:16: Arc.File.new(%{"filename" => "3x4.jpg", "path" => "uploads/customers/avatar/"})
(arc) lib/arc/actions/store.ex:9: Arc.Actions.Store.store/2
(arc_ecto) lib/arc_ecto/type.ex:18: Arc.Ecto.Type.cast/2
(ecto) lib/ecto/changeset.ex:568: Ecto.Changeset.cast_field/8
(ecto) lib/ecto/changeset.ex:524: Ecto.Changeset.process_param/7
(elixir) lib/enum.ex:1940: Enum."-reduce/3-lists^foldl/2-0-"/3
(ecto) lib/ecto/changeset.ex:501: Ecto.Changeset.cast/6
(fm_api) lib/fm_api/store/customer.ex:26: Api.Store.Customer.changeset/2
(fm_api) lib/fm_api/store.ex:92: Api.Store.create_customer/1
(fm_api) lib/fm_api_web/controllers/store/customer_controller.ex:45: ApiWeb.Store.CustomerController.create/2
(fm_api) lib/fm_api_web/controllers/store/customer_controller.ex:1: ApiWeb.Store.CustomerController.action/2
(fm_api) lib/fm_api_web/controllers/store/customer_controller.ex:1: ApiWeb.Store.CustomerController.phoenix_controller_pipeline/2
(fm_api) lib/fm_api_web/endpoint.ex:1: ApiWeb.Endpoint.instrument/4
(phoenix) lib/phoenix/router.ex:275: Phoenix.Router.__call__/1
(fm_api) lib/fm_api_web/endpoint.ex:1: ApiWeb.Endpoint.plug_builder_call/2
(fm_api) lib/plug/debugger.ex:122: ApiWeb.Endpoint."call (overridable 3)"/2
(fm_api) lib/fm_api_web/endpoint.ex:1: ApiWeb.Endpoint.call/2
(phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:33: Phoenix.Endpoint.Cowboy2Handler.init/2
(cowboy) /home/aislan/Projetos/Fascinante-Modas/backend-app/fm-api/deps/cowboy/src/cowboy_handler.erl:41: :cowboy_handler.execute/2
(cowboy) /home/aislan/Projetos/Fascinante-Modas/backend-app/fm-api/deps/cowboy/src/cowboy_stream_h.erl:296: :cowboy_stream_h.execute/3
As you can see, Arc.File.new can't get my parameters correctly.
In my frontend I have made ugly hacks because this, trying to make arc_ecto happy with my params. I'm sending the customer params along the file selected params to the create function in the customer_controller
Anyways, any helps will be apreciated!!
@aislanmaia I'm using arc and arc_ecto with Phoenix 1.4.8 and Ecto 3.1.7 and it's all fine here. I would double-check how you are sending data from the UI to the phoenix backend if you are still using React. Here is what my Phoenix template sends back to the server when I submit one:
Parameters: %{
"_csrf_token" => "blah-blah",
"_utf8" => "✓",
"relationship_attachment" => %{
"attachment" => %Plug.Upload{
content_type: "application/pdf",
filename: "DAR044A5BSLDD - Product Specifications.pdf",
path: "/var/folders/kz/9fl7k2_n3333brr2n853z1mc0000gn/T//plug-1562/multipart-1562943326-338726013807684-2"
},
"description" => "",
"name" => ""
}
My "relationship_attachment" is equivalent to your "customer" and my "attachment" key nested in there is equivalent to your "avatar" key.
I noticed you are not submitting a %Plug.Upload{} struct.