Hey guys, i’m working with liveview (generated by mix phx.gen.live ...
) and I’m not able to save an User.
When I try to press the save button, the following error is displayed:
no route found for POST /users/new (LivekbnWeb.Router)
Here’s my index:
defmodule LivekbnWeb.UserLive.Index do
use LivekbnWeb, :live_view
alias Livekbn.Users
alias Livekbn.Users.User
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, :users, list_users())}
end
@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end
defp apply_action(socket, :edit, %{"id" => id}) do
socket
|> assign(:page_title, "Edit User")
|> assign(:user, Users.get_user!(id))
end
defp apply_action(socket, :new, _params) do
socket
|> assign(:page_title, "New User")
|> assign(:user, %User{})
end
defp apply_action(socket, :index, _params) do
socket
|> assign(:page_title, "Listing Users")
|> assign(:user, nil)
end
@impl true
def handle_event("delete", %{"id" => id}, socket) do
user = Users.get_user!(id)
{:ok, _} = Users.delete_user(user)
{:noreply, assign(socket, :users, list_users())}
end
defp list_users do
Users.list_users()
end
end
My form_component liveview
defmodule LivekbnWeb.UserLive.FormComponent do
use LivekbnWeb, :live_component
alias Livekbn.Users
@impl true
def update(%{user: user} = assigns, socket) do
changeset = Users.change_user(user)
{:ok,
socket
|> assign(assigns)
|> assign(:changeset, changeset)}
end
@impl true
def handle_event("validate", %{"user" => user_params}, socket) do
changeset =
socket.assigns.user
|> Users.change_user(user_params)
|> Map.put(:action, :validate)
{:noreply, assign(socket, :changeset, changeset)}
end
def handle_event("save", %{"user" => user_params}, socket) do
save_user(socket, socket.assigns.action, user_params)
end
defp save_user(socket, :edit, user_params) do
case Users.update_user(socket.assigns.user, user_params) do
{:ok, _user} ->
{:noreply,
socket
|> put_flash(:info, "User updated successfully")
|> push_redirect(to: socket.assigns.return_to)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, :changeset, changeset)}
end
end
defp save_user(socket, :new, user_params) do
case Users.create_user(user_params) do
{:ok, _user} ->
{:noreply,
socket
|> put_flash(:info, "User created successfully")
|> push_redirect(to: socket.assigns.return_to)}
{:error, %Ecto.Changeset{} = changeset} ->
{:noreply, assign(socket, changeset: changeset)}
end
end
end
My form_component.leex
<h2><%= @title %></h2>
<%= f = form_for @changeset, "#",
id: "user-form",
phx_target: @myself,
phx_change: "validate",
phx_submit: "save" %>
<%= label f, :name %>
<%= text_input f, :name %>
<%= error_tag f, :name %>
<%= label f, :email %>
<%= text_input f, :email %>
<%= error_tag f, :email %>
<%= label f, :password_hash %>
<%= text_input f, :password_hash %>
<%= error_tag f, :password_hash %>
<%= submit "Save", phx_disable_with: "Saving..." %>
</form>
router
defmodule LivekbnWeb.Router do
use LivekbnWeb, :router
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_live_flash
plug :put_root_layout, {LivekbnWeb.LayoutView, :root}
plug :protect_from_forgery
plug :put_secure_browser_headers
end
pipeline :api do
plug :accepts, ["json"]
end
scope "/", LivekbnWeb do
pipe_through :browser
live "/", PageLive, :index
live "/users", UserLive.Index, :index
live "/users/new", UserLive.Index, :new
live "/users/:id/edit", UserLive.Index, :edit
live "/users/:id", UserLive.Show, :show
live "/users/:id/show/edit", UserLive.Show, :edit
live "/tasks", TaskLive.Index, :index
live "/tasks/new", TaskLive.Index, :new
live "/tasks/:id/edit", TaskLive.Index, :edit
live "/tasks/:id", TaskLive.Show, :show
live "/tasks/:id/show/edit", TaskLive.Show, :edit
#post "/tasks/new", TasksController, :new
end
# Other scopes may use custom stacks.
# scope "/api", LivekbnWeb do
# pipe_through :api
# end
# Enables LiveDashboard only for development
#
# If you want to use the LiveDashboard in production, you should put
# it behind authentication and allow only admins to access it.
# If your application does not have an admins-only section yet,
# you can use Plug.BasicAuth to set up some basic authentication
# as long as you are also using SSL (which you should anyway).
if Mix.env() in [:dev, :test] do
import Phoenix.LiveDashboard.Router
scope "/" do
pipe_through :browser
live_dashboard "/dashboard", metrics: LivekbnWeb.Telemetry
end
end
end
How do I make it work?
Thank you for your patience