Plug.Conn shopping cart: is_nil() check renders value nil?

So I have a shopping cart that I tied to the session with this great package:

anyway, I’m allowing the user to add to the cart(which is a list of product ids) while they are not logged-in. So when they do log in, I want to put the shopping cart list into the new session:

cart = if(is_nil(cart), do: [])
  def login_user(conn, user, params \\ %{}) do
    cart = get_session(conn, "shopping_cart")
    IO.inspect(cart, label: "UserAuth login_user shopping_cart")

    # cart can be nil if the unlogged-in user didn't add something to the cart
    cart = if(is_nil(cart), do: [])
    IO.inspect(cart, label: "UserAuth login_user shopping_cart")

    token = Accounts.generate_user_session_token(user, params["org_id"])
    user_return_to = get_session(conn, :user_return_to)

    conn
    |> renew_session()
    |> put_session(:user_token, token)
    |> put_session(:live_socket_id, "users_sessions:#{Base.url_encode64(token)}")
    |> put_session("shopping_cart", cart)
    |> maybe_write_remember_me_cookie(token, params)
    |> redirect(to: user_return_to || signed_in_path(conn))

    conn
  end

The above line cart = if(is_nil(cart), do: []) seems make the shopping_cart nil:

UserAuth login_user shopping_cart: ["prod_IpMCdH7VQv1bWz", "prod_IpMCdH7VQv1bWz", "prod_IpMCdH7VQv1bWz"]
UserAuth login_user shopping_cart: nil

Am I missing something here when it comes to how get_session() and put_session() work?

    cart = if(is_nil(cart), do: [])

This line is equivalent to:

cart = if is_nil(cart) do
  []
else
  nil
end

This is probably not what you want, because if cart is NOT nil then it sets it to nil. From your logic it seems like what you want is:

cart = get_session(conn, "shopping_cart") || []

This will get the value from the session and if it is nil, instead default to [].

3 Likes

Nice idiom, that nailed it. Thanks!

1 Like