I have a liveview called Menu with 3 Live Component Categories, Products, and Variants
phx-click set up on each category, product, so when click on category, handle_event will
return assign(socket, :products, products) ProductsComponent will products for the clicked category, and click on product, Variants will show.
And the handle_events are inside the Menu View
defmodule MyAppWeb.Admin.LocationLive.Menu do
use MyAppWeb, :live_view
import MyAppWeb.Admin.LocationLive.Helpers,
only: [
get_categories: 1,
get_products: 2,
get_variants: 2
]
alias MyApp.Manager.Base
@impl true
def mount(%{"id" => location_id}, _session, socket) do
case Base.get_location(location_id) do
nil ->
{:noreply, redirect(socket, Routes.admin_business_path(MyAppWeb.Endpoint, :index))}
location ->
{:ok,
socket
|> assign(:page_title, "Menu")
|> assign(:location, location)
|> assign(:products, [])
|> assign(:variants, [])
|> assign(:selected_category_id, nil)
|> assign(:selected_product_id, nil)
|> assign(:categories, get_categories(location)), temporary_assigns: [categories: []]}
end
end
@impl true
def handle_event(
"show-products",
%{"category" => category_id},
socket
) do
location = get_location(socket)
{:noreply,
socket
|> assign(:products, get_products(location, category_id))
|> assign(:variants, [])
|> assign(:selected_category_id, category_id)}
end
@impl true
def handle_event(
"show-variants",
%{"product" => product_id},
socket
) do
location = get_location(socket)
{:noreply,
socket
|> assign(:variants, get_variants(location, product_id))
|> assign(:selected_product_id, product_id)}
end
defp get_location(socket) do
socket.assigns.location
end
end
menu.html.leex
<div class="row">
<div class="<%= row_parts_class(4) %>">
<div class="align-items-center <%= row_parts_class(12) %>">
<h5 class="h5 font-weight-bold text-default">Categories</h5>
</div>
<%= live_component @socket, MyAppWeb.Admin.LocationLive.CategoriesComponent,
categories: @categories,
location: @location,
id: "categories-component"
%>
</div>
<div class="<%= row_parts_class(4) %>">
<div class="align-items-center <%= row_parts_class(12) %>">
<h5 class="h5 font-weight-bold text-default">Products</h5>
</div>
<%= live_component @socket, MyAppWeb.Admin.LocationLive.ProductsComponent,
products: @products,
location: @location,
category_id: @selected_category_id,
id: "products-component"
%>
</div>
<div class="<%= row_parts_class(4) %>">
<div class="align-items-center <%= row_parts_class(12) %>">
<h5 class="h5 font-weight-bold text-default">Variants</h5>
</div>
<%= live_component @socket, MyAppWeb.Admin.LocationLive.VariantsComponent,
variants: @variants,
location: @location,
product_id: @selected_product_id,
id: "variants-component"
%>
</div>
</div>
My problem is that after clicking on product, and variants are shown, then I go back to click on another category, it will show new products, but the old variants are still there. So I tried to assign(socket, :variants, []) in category handle_event, but it throws an error in console no component for CID 2, and the old Products and Variants components remain unchanged.
Anyone has any idea how to fix this or maybe a workaround to clear out the VariantsComponent everytime a category is clicked?
Thanks!
