Hi,
This seems to be strange for me, but without any updates of libraries or even elixir part of app doesnt work like before.
I have got few views which show list of products, categories, brands etc. Problem seems to be repeated everytime being in show window. Instead of adding to cart or refuse adding to cart it invokes error with event_handler from index window. I will paste just code from ex and html for one of those, because code is similar everywhere and problem seems to happens everytime (sometimes it works if I open VSCode and add IO.inspect() on handler an save it (LOL), but after few tries it crashes again)
category_index.ex
@impl true
def mount(_params, %{"user_token" => user_token}, socket) do
user = Accounts.get_user_by_session_token(user_token)
{:ok,
socket
|> assign(:current_user, user)
|> assign(:categories, Catalog.list_categories())}
end
def mount(_params, _session, socket) do
{:ok, assign(socket, :categories, Catalog.list_categories())}
end
@impl true
def handle_params(params, _url, socket) do
{:noreply, apply_action(socket, socket.assigns.live_action, params)}
end
defp apply_action(socket, :show, %{"id" => id}) do
socket
|> assign(:page_title, "Show Category")
|> assign(:category, Catalog.get_category!(id))
|> assign(:products, Catalog.get_available_products_by_category_id(id))
end
defp apply_action(socket, :index, _params) do
socket
|> assign(:page_title, "Listing Categories")
|> assign(:category, nil)
end
end
category_index.html.heex
<div class="bg-white mx-auto h-screen justify-items-center">
<section class="mx-auto max-w-screen-lg justify-items-center mt-10 mb-5">
<img
alt="category image"
src={ ~s[/images/main-site-photo.jpg]}>
</section>
<div class="mx-auto mb-10">
<p class="text-center text-blue-500 md:text-2xl sm:text-xl">The best equipment for your office</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 mx-auto justify-center max-w-7xl">
<%= for category <- @categories do %>
<%= live_redirect to: Routes.category_show_path(@socket, :show, category.id) do %>
<div class="flex flex-col content-between justify-center mx-auto my-10 " id={"category-#{category.id}"}>
<div class="self-center w-64 h-64">
<img
alt="category image" width="250" height="250"
src={ Routes.static_path(@socket, category.image_upload || ~s[/images/default-thumbnail.jpg])} >
</div>
<p class="text-center text-blue-500 md:text-2xl sm:text-xl mt-5"><%= category.name %></p>
</div>
<% end %>
<% end %>
</div>
</div>
As Its written - this window contains only redirections to specific categories and list of products in it. Zero event_handlers, I dont even know if I need handle_params here…
and
category_show.ex
@impl true
def mount(_params, %{"user_token" => user_token}, socket) do
user = Accounts.get_user_by_session_token(user_token)
{:ok,
socket
|> assign(:current_user, user)
|> assign(:cart, ShoppingCart.get_cart_by_user_id(user.id))
|> assign(:cart_items, %CartItem{})}
end
def mount(_params, _session, socket) do
{:ok, socket}
end
@impl true
def handle_event("add_to_cart", %{"product" => product_id, "quantity" => quantity}, socket) do
IO.inspect(product_id)
IO.inspect(quantity)
case socket.assigns[:current_user] do
%Eshopy.Accounts.User{role: :user} ->
create_and_add_item(product_id, quantity, socket)
_ ->
{:noreply,
socket
|> put_flash(:info, "You must be logged in")}
end
end
@impl true
def handle_params(%{"id" => id}, _, socket) do
{:noreply,
socket
|> assign(:page_title, "Show Category")
|> assign(:category, Catalog.get_category!(id))
|> assign(:products, Catalog.get_available_products_by_category_id(id))}
end
defp create_and_add_item(product_id, quantity, socket) do
product = Catalog.get_product!(product_id)
quantity = String.to_integer(quantity)
socket =
case ShoppingCart.get_cart_by_user_id(socket.assigns.current_user.id) do
%Cart{} = cart ->
add_item_to_shopping_cart(socket, cart, product, quantity)
nil ->
{:ok, %Cart{} = cart} = ShoppingCart.create_cart(socket.assigns.current_user)
add_item_to_shopping_cart(socket, cart, product, quantity)
end
{:noreply, socket}
end
defp add_item_to_shopping_cart(socket, cart, product, quantity) do
case ShoppingCart.add_item_to_cart(cart, product, quantity) do
{:ok, _item} ->
socket
|> put_flash(:info, "Item added to shopping cart")
{:error, _changeset} ->
socket
|> put_flash(:info, "Error with adding item")
end
end
end
category_show.html.heex
<div>
<p class="text-center text-blue-500 md:text-2xl text-xl"><strong><%= @category.name %></strong></p>
<div class="flex flex-wrap mx-auto justify-center max-w-7xl">
<%= for product <- @products do %>
<div class="flex flex-col mx-auto my-5">
<%= live_redirect to: Routes.product_show_path(@socket, :show, product.id) do %>
<div class="grid grid-cols-1 content-center justify-center mx-auto" id={"product-#{product.id}"}>
<div class="self-center w-64 h-64">
<img
alt="product image" width="250" height="250"
src={ product.image_upload } >
</div>
<p class="text-center text-blue-500 md:text-2xl sm:text-xl mt-5"><strong><%= product.name %></strong></p>
<p class="text-center text-blue-500 md:text-xl sm:text-xl"><%= Catalog.get_category!(product.category_id).name %></p>
<p class="text-center text-blue-500 md:text-2xl sm:text-xl"><em><%= product.unit_price %>$</em></p>
</div>
<% end %>
<button class="bg-blue-400 text-white font-[Poppins] duration-500 px-6 py-2 md:my-0 hover:bg-blue-600 rounded" phx-click="add_to_cart" phx-value-product={product.id} phx-value-quantity={1}>Add to cart</button>
</div>
<% end %>
</div>
</div>
Being in show window I click add_to_cart. It doesnt matter if I am logged in or not it crashes and redirects me to category_index page (even if i receive flash that Product has been added to cart :D) and terminal becomes red with error like that:
I paste all of it, maybe someone catches things that i can not.
[error] GenServer #PID<0.1152.0> terminating
** (UndefinedFunctionError) function EshopyWeb.BrandLive.Index.handle_event/3 is undefined or private
(eshopy 0.1.0) EshopyWeb.BrandLive.Index.handle_event("add_to_cart", %{"product" => "5", "quantity" => "1", "value" => ""}, #Phoenix.LiveView.Socket<assigns: %{__changed__: %{}, brand: nil, brands: [%Eshopy.Catalog.Brand{__meta__: #Ecto.Schema.Metadata<:loaded, "brands">, id: 1, image_upload: "/images/live_view_upload-1675197775-472722086641-2", inserted_at: ~N[2023-01-31 20:42:59], name: "Huawei", products: #Ecto.Association.NotLoaded<association :products is not loaded>, updated_at: ~N[2023-01-31 20:42:59]}, %Eshopy.Catalog.Brand{__meta__: #Ecto.Schema.Metadata<:loaded, "brands">, id: 2, image_upload: "/images/live_view_upload-1675197790-688965978619-1", inserted_at: ~N[2023-01-31 20:43:11], name: "Apple", products: #Ecto.Association.NotLoaded<association :products is not loaded>, updated_at: ~N[2023-01-31 20:43:11]}, %Eshopy.Catalog.Brand{__meta__: #Ecto.Schema.Metadata<:loaded, "brands">, id: 3, image_upload: "/images/live_view_upload-1675197802-989508123695-6", inserted_at: ~N[2023-01-31 20:43:24], name: "Logitech", products: #Ecto.Association.NotLoaded<association :products is not loaded>, updated_at: ~N[2023-01-31 20:43:24]}], current_user: #Eshopy.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, confirmed_at: nil, customer: #Ecto.Association.NotLoaded<association :customer is not loaded>, email: "admin@pl", id: 1, inserted_at: ~N[2023-01-31 20:37:48], role: :user, updated_at: ~N[2023-02-08 16:52:14], ...>, flash: %{}, live_action: :index, page_title: "Listing Brands"}, endpoint: EshopyWeb.Endpoint, id: "phx-F0SISDHsRoJ5PgQJ", parent_pid: nil, root_pid: #PID<0.1152.0>, router: EshopyWeb.Router, transport_pid: #PID<0.1140.0>, view: EshopyWeb.BrandLive.Index, ...>)
(phoenix_live_view 0.17.12) lib/phoenix_live_view/channel.ex:382: anonymous fn/3 in Phoenix.LiveView.Channel.view_handle_event/3
(telemetry 1.1.0) /home/mateusz/Pulpit/eshopy/deps/telemetry/src/telemetry.erl:320: :telemetry.span/3
(phoenix_live_view 0.17.12) lib/phoenix_live_view/channel.ex:216: Phoenix.LiveView.Channel.handle_info/2
(stdlib 4.0.1) gen_server.erl:1120: :gen_server.try_dispatch/4
(stdlib 4.0.1) gen_server.erl:1197: :gen_server.handle_msg/6
(stdlib 4.0.1) proc_lib.erl:250: :proc_lib.wake_up/3
Last message: %Phoenix.Socket.Message{event: "event", join_ref: "7", payload: %{"event" => "add_to_cart", "type" => "click", "value" => %{"product" => "5", "quantity" => "1", "value" => ""}}, ref: "20", topic: "lv:phx-F0SISDHsRoJ5PgQJ"}
State: %{components: {%{}, %{}, 1}, join_ref: "7", serializer: Phoenix.Socket.V2.JSONSerializer, socket: #Phoenix.LiveView.Socket<assigns: %{__changed__: %{}, brand: nil, brands: [%Eshopy.Catalog.Brand{__meta__: #Ecto.Schema.Metadata<:loaded, "brands">, id: 1, image_upload: "/images/live_view_upload-1675197775-472722086641-2", inserted_at: ~N[2023-01-31 20:42:59], name: "Huawei", products: #Ecto.Association.NotLoaded<association :products is not loaded>, updated_at: ~N[2023-01-31 20:42:59]}, %Eshopy.Catalog.Brand{__meta__: #Ecto.Schema.Metadata<:loaded, "brands">, id: 2, image_upload: "/images/live_view_upload-1675197790-688965978619-1", inserted_at: ~N[2023-01-31 20:43:11], name: "Apple", products: #Ecto.Association.NotLoaded<association :products is not loaded>, updated_at: ~N[2023-01-31 20:43:11]}, %Eshopy.Catalog.Brand{__meta__: #Ecto.Schema.Metadata<:loaded, "brands">, id: 3, image_upload: "/images/live_view_upload-1675197802-989508123695-6", inserted_at: ~N[2023-01-31 20:43:24], name: "Logitech", products: #Ecto.Association.NotLoaded<association :products is not loaded>, updated_at: ~N[2023-01-31 20:43:24]}], current_user: #Eshopy.Accounts.User<__meta__: #Ecto.Schema.Metadata<:loaded, "users">, confirmed_at: nil, customer: #Ecto.Association.NotLoaded<association :customer is not loaded>, email: "admin@pl", id: 1, inserted_at: ~N[2023-01-31 20:37:48], role: :user, updated_at: ~N[2023-02-08 16:52:14], ...>, flash: %{}, live_action: :index, page_title: "Listing Brands"}, endpoint: EshopyWeb.Endpoint, id: "phx-F0SISDHsRoJ5PgQJ", parent_pid: nil, root_pid: #PID<0.1152.0>, router: EshopyWeb.Router, transport_pid: #PID<0.1140.0>, view: EshopyWeb.BrandLive.Index, ...>, topic: "lv:phx-F0SISDHsRoJ5PgQJ", upload_names: %{}, upload_pids: %{}}
To make it works I need to copy/paste all handlers to index.ex what sounds like a bull***t.
Recently I started using socket and channels to track users - after that feature it started to showing me that error. Is is possible that its the reason? Logically it shouldnt be…