I've recently started to learn Elixir and I'm really quite enjoying it, but it's the first functional programming language I've ever used. The problem I'm faced with is from what I've been reading through tutorials and watching screencasts at LearnElixir is that you should try to avoid using IF
type statements.
But I find myself constantly nesting cond
or case
I would solve these solutions in other languages like Golang or Javascript by just using an if statment with an early return, so that the code beyond that would not run, this prevented me 99% of the time from having to nest conditionals by just checking falsy values and returning.
So in Elixir
(or other functional programming languages) how would you go about writing something like the below in a proper way without using nesting, and taking advantage of the functionality of the language.
def loginPost(conn, %{"user" => user_params}) do
# Look for user in database
query = from u in User,
where: u.email == ^user_params["email"],
select: [u.email, u.username, u.password]
data = Repo.all(query)
# Check to see if a user had been found
case (length data) == 0 do
true -> # No user was found, send an error message
conn
|> json(%{ success: false, errors: ["Wrong username or password"]})
false -> # A user was found, compare password
[[email, username, db_password]] = data
case Comeonin.Bcrypt.checkpw(user_params["password"], db_password) do
true -> # Password was correct, set session and return a json response
conn
|> put_session(:authenticated, true)
|> put_session(:username, username)
|> put_session(:email, email)
|> json(%{success: true}) # Send json response and redirect on client side
false -> # Password was incorrect, send an error message
conn
|> json(%{success: false, errors: ["Wrong username or password"]})
end
end
end
end
if
is used. – Jason Hu