If your map contains keys like :date
, :time
, etc., then your code above won’t work (because it matches an entry with key :entries
).
There are a few possible ways to solve this. First, you could check if any of the entry fields is blank. Remember that maps are Enumerable
, so you can enumerate them as a collection of {key, value}
with the Enum
module:
def add_entry(todo_server, new_entry) do
if Enum.any?(new_entry, fn {_key, value} -> value == nil || value == "" end) do
IO.puts("input cannot be empty!")
else
GenServer.cast(todo_server, {:add_entry, new_entry})
end
end
Instead of printing an output though, it would be better to return an error, so the caller can pattern match easily. Usually, one would return :ok
or {:error, reason}
:
def add_entry(todo_server, new_entry) do
if Enum.any?(new_entry, fn {_key, value} -> value == nil || value == "" end) do
{:error, "input cannot be empty!"}
else
GenServer.cast(todo_server, {:add_entry, new_entry})
end
end
If the entries always have the same keys, there is a possibly better way to do this: you can use a struct for the entry, instead of a map, to enforce the “shape” of the entry:
defmodule Todo.Server do
defmodule Entry do
@enforce_keys [:date, :time, :title]
defstruct [:date, :time, :title]
end
def add_entry(todo_server, %Entry{date: date, time: time, title: title})
when is_nil(date) or is_nil(time) or is_nil(title) or title == "" do
{:error, "input cannot be empty!"}
end
def add_entry(todo_server, new_entry = %Entry{}) do
GenServer.cast(todo_server, {:add_entry, new_entry})
end
def add_entry(_server, _entry), do: {:error, "Invalid input"}
end
This way, the entry is now a struct that enforces that all of :date
, :time
, and :value
are present. This also mean, though, that the caller of the add_entry
function has to pass an Entry
struct instead of a map, so it’s your choice whether this is desirable or not.
P.S.:
Unrelated to your question, but you might want to use GenServer.call/3
instead of GenServer.cast/2
, even if you don’t need a result. The reason is explained here: https://elixir-lang.org/getting-started/mix-otp/genserver.html#call-cast-or-info