Elixir passing value while redirection And put_flash

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.

  1. Both put_flash functions don’t work.
  2. I do not know how to pass additional values from login (while redirect there is userp: userp value, which is not provided in the :main, and not in the render in the :main). How could I add these additional arguments? Right now it only keeps user name, but later on I want it to handle the whole user specification from the database (it is working right now). Below is code

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!!!

put_flash returns an updated conn containing the updated flash. Discarding the return value from put_flash discards that data.

Because of this, you’ll frequently see pipelines of conn-manipulating functions:

    case userSpec do
      nil ->
        conn
        |> put_flash(:error, "Could not find the user")
        |> redirect(to: Routes.grant_path(conn, :index), users: users, changeSet: changeSet)

Some other general notes:

  • redirect makes a URL and includes it in the Location: header in the response. Passing lists of structs like users will not do what you want.

  • for unsaved data, you could use the session. See the Phoenix docs for details

  • for saved data like users, you should always retrieve the values from the DB - otherwise you could get skew where sessions hold stale data

2 Likes

So how can I add values which will be redireted into :main? Like I would like to insert new arguments,which are not included in :main render?