I have a LiveView that contains a text input field with phx-change
tied to an event called “search” that searches locations in the database for the string in the text input field, and displays the results of @streams.locations
using the table core component.
Each location item on the table has a “keep” action that gets triggered with JS.push
, which adds the item to a “kept” list of locations in assigns
. This way the user adds items from the search results’ stream (@streams.locations
) to a list, before committing this “kept” list to the database with another button.
How do I implement an action that applies the “keep” action on the entire @streams.locations
, i.e. a “keep all” action?
I tried a button with phx-click={JS.push("keep_all")}
and then accessing socket.assigns.streams.locations
within handle_event("keep_all", _params, socket)
, but IIUC the LiveView has no knowledge of what’s shown in the browser, as the stream items are not in memory.
I then tried something like this:
JS.push("keep_all", value: %{locations: Enum.with_index(@streams.locations)})
and got:
** (ArgumentError) streams can only be consumed directly by a for comprehension.
If you are attempting to consume the stream ahead of time, such as with
`Enum.with_index(@streams.locations)`, you need to place the relevant information
within the stream items instead.
In other words: what is the idiomatic way of using JS.push
to trigger an event that does something across all items in streams.something
?