login function should take the variable provided by the user in the form, and then is checking if the given user exists in the database. If yes, he will be redirected to main site, if not, he will be redirected to the same form to submit again his name. I have two problems.
login function:
def login(conn, %{"user" => userp}) do
changeSet = RewardappWeb.User.changeset(%RewardappWeb.User{}, userp)
#IO.inspect(userp)
users = Rewardapp.Repo.all(RewardappWeb.User)
#IO.inspect(changeSet)
#VALIDATION, IF GIVEN USER BELONGS TO DATABASE
value = userp["user"]
#map of lists
listOfUsers = Rewardapp.Repo.all(RewardappWeb.User)
IO.inspect(Enum.find(listOfUsers, fn x -> x.name == value end))
userSpec = Enum.find(listOfUsers, fn x -> x.name == value end)
IO.inspect(userSpec)
case userSpec do
nil ->
put_flash(conn, :error, "Could not find the user")
#render(conn, "index.html", users: users, changeSet: changeSet)
redirect(conn, to: Routes.grant_path(conn, :index), users: users, changeSet: changeSet)
_ ->
put_flash(conn, :info, "Logged in")
#render(conn, "start.html", changeSet: changeSet, users: users, userp: userp)
redirect(conn, to: Routes.grant_path(conn, :main), users: users, changeSet: changeSet, userp: userp)
end
end
main function:
def main(conn, params) do
changeSet = RewardappWeb.User.changeset(%RewardappWeb.User{}, %{})
users = Rewardapp.Repo.all(RewardappWeb.User)
render(conn, "start.html", changeSet: changeSet, users: users)
end
index function :
def index(conn, params) do
changeSet = RewardappWeb.User.changeset(%RewardappWeb.User{}, %{})
render(conn, "index.html", changeSet: changeSet)
end
the router.ex looks like this:
get "/main", GrantController, :main
get "/", GrantController, :index
post "/users", GrantController, :login
Thanks you in advance for any helping!!!
Elixir is a functional language. You can't mutate "classes" in place and then use them after mutation, or anything like that.
case userSpec do
nil ->
put_flash(conn, :error, "Could not find the user")
redirect(conn, to: Routes.grant_path(conn, :index), users: users, changeSet: changeSet)
# ...
end
Your put_flash(conn, ...) call will create a modified conn and throw it into the ether.
Then the redirect(conn, ...) call will modify the original conn (the one without the flash, not the one with the flash) and that's what your login function actually ends up returning.
So that's why the redirect works, but there is no plash - it wasn't added to the conn you're returning.
So what you want to do is something like
case userSpec do
nil ->
conn
|> put_flash(:error, "Could not find the user")
|> redirect(to: Routes.grant_path(conn, :index), users: users, changeSet: changeSet)
# ...
end
I.E. you add the flash to the conn, then redirect the result, and that's what your function should return.
I hope that helps.
As for adding additional arguments to the redirect, it depends on what you want to add. If it's query params, then you could do
path = Routes.grant_path(conn, :index, %{"foo" => "bar"})
redirect(conn, to: path)
The other way to add data would be to put it in session.
I'm guessing what you actually want is add data that is then used in the html you're rendering. Redirection doesn't work that way. It's basically telling the browser, go to this other location and go through the request process from the beginning.
In some cases, you might be able to render a different view template, rather than redirecting and achieve what you want.
render(conn, "index.json", user: user, changeset: changeset)
But whether that's possible here really depends on your specific case.