Hi, I’m trying to leverage liveview surface to render a list of points eventually converting that list to coordinates to create tetro shapes for a tetris game. I can view the list of points on the live_view page by inspecting the shape and calling a function retrieving the points.
def render(assigns) do
~F"""
<Title message={@title} id="title" />
<pre>
{ inspect Shape.from_tetro(@tetro) }
</pre>
"""
end
@impl true
def mount(_params, _session, socket) do
{:ok, assign(socket, tetro: Tetro.new(:j), title: "Welcome to FreeFall!")}
end
The issue we’re seeing is when we’re trying to obtain that list from within a surface component. That will be used above. Elixir complains about @points and we’re explicitly setting it in the mount callback. Am I overlooking something?
defmodule FreeFallWeb.Live.Components.Shape do
use Surface.LiveComponent
alias FreeFall.Game.Shape
prop(tetro, :map, required: true)
def mount(socket, %{position: position} = tetro) do
{:ok, assign(socket, position: position, points: Shape.from_tetro(tetro))}
end
def render(assigns) do
~F"""
{#for point <- @points}
{inspect point}
{/for}
"""
end
end
Depending on how complicated your live view is, how many shapes you have on the page, etc, it might be more performant to handle them in the view. There is a slight cost to live components vs function components.
Thanks for your help, greatly appreciated. we’ve simplified the component and were able to retrieve the points through setting the properties at the liveview level to the Shape component which we got working by adding the declaration for points in the Shape component. Using a comprehension we’ll be emitting a Point component per point tuple.