I have a list of notes to show using LiveView stream, and I want to use an assign called online_users_map
continuously updated by Phoenix Presence, in order to show which note's author is currently online . In the sample code below, I noticed the first inspect prints the updated map as users join or leave, but the second inspect remains %{} which leads me to think assigns in a stream phx-update block of code is static. Is that correct? If so, how do I make the dynamically changing assign value available in the stream block?
<div>
<%= inspect(@online_users_map) %> <<< This prints correctly
<ul
phx-update="stream"
phx-viewport-top={@page_no > 1 && "prev-page"}
phx-viewport-bottom={!@end_of_timeline? && "next-page"}
phx-page-loading
id="searched_notess"
class={[
if(@end_of_timeline?, do: "pb-4", else: "pb-[calc(200vh)]"),
if(@page_no == 1, do: "pt-4", else: "pt-[calc(200vh)]")
]}
>
<%= inspect(@online_users_map) %> <<< This only prints %{}
<li
:for={{dom_id, note} <- @streams.searched_notes}
class="pb-2 sm:pb-2 mt-2 flex flex-row "
id={dom_id}
>
phx-update
is used to prevent any changes in the LiveView. When setting it to phx-update="stream"
the HTML is rendered based on the streams content, but then the data, e.g. @streams.searched_notes
is removed from the socket assigns (see LiveView stream docs). So I would agree, that the HTML rendered inside the stream-block is "static" and you can change only it by using stream_insert
and stream_delete
on server side.
Therefore, I believe, the only way to access the @online_users_map
assigns would be to integrate the data into the @stream.searched_notes
. Probably as another field inside a note
element, such as author_online: <true | false>
. Of course this would only work if you plan to display the information for each note
, but this is not described in the question.