romenigld
How to validate an array of strings for the upload files in Phoenix LiveView
Hello Guys,
I was doing the course of the PraProg Phoenix LiveView Pro and I was trying to do a validation for the upload files.
For example If I try to put just the name of the desks and not put any file for upload, I would like to show the validation for upload a file.
I tried to add a validate_required for the photo_urls on the changeset:
defmodule LiveViewStudio.Desks.Desk do
use Ecto.Schema
import Ecto.Changeset
schema "desks" do
field :name, :string
field :photo_urls, {:array, :string}, default: []
timestamps()
end
@doc false
def changeset(desk, attrs) do
desk
|> cast(attrs, [:name, :photo_urls])
|> validate_required([:name, :photo_urls])
end
end
But if I put just the name for the desks, the photo_urls are not validated.
as you can see the log:
[debug] QUERY OK db=2.1ms queue=1.3ms idle=1529.6ms
INSERT INTO "desks" ("name","photo_urls","inserted_at","updated_at") VALUES ($1,$2,$3,$4) RETURNING "id" ["Testing", [], ~N[2021-04-19 17:20:41], ~N[2021-04-19 17:20:41]]
But on the application this values are not showed. It shows only the those which have photo_urls.
But If I try to list all Desks, like:
iex> Desks.list_desks()
The empty photo_urls are recorded:
%LiveViewStudio.Desks.Desk{
__meta__: #Ecto.Schema.Metadata<:loaded, "desks">,
id: 17,
inserted_at: ~N[2021-04-16 21:11:22],
name: "Testing",
photo_urls: [],
updated_at: ~N[2021-04-16 21:11:22]
},
How can I validate an empty array of strings for the :photo_urls?
Marked As Solved
romenigld
When I arrived in home I was thinking in to inspect the values.
So I do this:
defmodule LiveViewStudio.Desks.Desk do
use Ecto.Schema
import Ecto.Changeset
schema "desks" do
field :name, :string
field :photo_urls, {:array, :string}, default: []
timestamps()
end
@doc false
def changeset(desk, attrs) do
desk
|> cast(attrs, [:name, :photo_urls])
|> validate_required([:name])
|> validate_empty_photo_urls()
end
def validate_empty_photo_urls(changeset) do
photos = get_field(changeset, :photo_urls)
IO.inspect(photos, label: "Photos")
if Enum.empty?(photos) do
changeset = add_error(changeset, :photo_urls, "must insert a photo!")
IO.inspect(changeset, label: "changeset")
else
changeset
end
end
end
So in the log shows me this:
Photos: []
changeset: #Ecto.Changeset<
action: nil,
changes: %{name: "test"},
errors: [photo_urls: {"must insert a photo!", []}],
data: #LiveViewStudio.Desks.Desk<>,
valid?: false
And I can see it was working the validations and it wasn’t inserted in the database when I click on the button Upload.
So I was seeking why not it was showed the error and the thing is not having the error_tag for the :photo-urls.
So I add the error_tag on the beginning of the drag-and-drop div:
<div class="drop" phx-drop-target="<%= @uploads.photo.ref %>">
<div>
<%= error_tag f, :photo_urls %>
<img src="/images/upload.svg">
<div>
<label for="<%= @uploads.photo.ref %>">
<span>Upload a file</span>
<%= live_file_input @uploads.photo, class: "sr-only" %>
</label>
<span>or drag and drop</span>
</div>
<p>
<%= @uploads.photo.max_entries %> photos max,
up to <%= trunc(@uploads.photo.max_file_size / 1_000_000) %> MB each
</p>
</div>
</div>
And now it’s working! ![]()
Thank you for the help guys, it was very helpful!
Also Liked
cenotaph
my apologies, different language mix up there! I have corrected my post
romenigld
Yes I know in the course it doesn’t cast the :photo_urls.
But I was testing to put just the :name and no files for uploads.
And then I notice it was saving on the database, but they don’t are showing.
So I was trying to do a validate in the schema.
For now your help make more sense.
But it would be nice to do this on the schema.
I will review some books, I think I saw something which is possible creating a custom validation.
I just don’t know how to do it now.
thank you for reply @f0rest8!
sfusato
It invokes the
validatorfunction to perform the validation only if a change for the givenfieldexists and the change value is notnil. The function must return a list of errors (with an empty list meaning no errors).
- when the value is
nil, the validator function won’t even be called; I believe you defined:photo_urlsas an array of strings with the default value being empty list; - you must return a list of errors,
[photo_urls: "must insert a photo!"], in the error case []in the no error case
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










