Extends Phoenix LiveView with stream_async/4
macro.
Similar to existing assign_async/4
, but for streams.
The package can be installed by adding live_stream_async
to your list of dependencies in mix.exs
:
def deps do
[
{:live_stream_async, "~> 0.1.0", runtime: false}
]
end
The docs can be found at https://hexdocs.pm/live_stream_async.
Streams in LiveView allow working with large collections without keeping them on the server. In case you want to work with streams
assigns asynchronously you may need to resort to low level control functions.
This library provides a convenient macro stream_async/4
that auto-generates all the necessary boilerplate behind the scenes and injects it into your LiveView module.
Extend your live view module with use LiveStreamAsync
and you can leverage the stream_async/4
macro:
use MyAppWeb, :live_view
use LiveStreamAsync
def mount(%{"location" => location}, _, socket) do
{:ok,
socket
|> stream_configure(:hotels, dom_id: &"hotel-#{&1.id}")
|> stream_async(:hotels, fn -> Hotels.fetch!(location) end, reset: true)
}
end
The <.async_result ...>
component is designed to work with the %Phoenix.LiveView.AsyncResult{}
structs. The struct is passed via "assign={}
" attribute of the component. The component's inner block receives the @streams
assign key through :let={}
attribute.
Example:
def render(assigns) do
~H"""
<.async_result :let={stream_key} assign={@hotels}>
<:loading>Loading hotels...</:loading>
<:failed :let={_failure}>There was an error loading the hotels. Please try again later.</:failed>
<ul id="hotels_stream" phx-update="stream">
<li :for={{id, hotel} <- @streams[stream_key]} id={id}>
<%= hotel.name %>
</li>
</ul>
</.async_result>
"""
end
Note: in the example above just replace "@hotels" with the id of your stream.
New release of LiveView library - v 0.20 - introduced built-in functions for asynchronous work. It's a perfect solution to deliver a snappy user experience by delegating some time-consuming tasks (ex. fetching from external services) to background jobs without blocking the UI or event handlers. New operations include:
assign_async/4
: a straight forward way to load the results asynchronously into socket assigns.start_async/3
: allows lower level control of asynchronous operations withhandle_async
callbacks.<.async_result ...>
- function component to handle the asynchronous operation state on the UI side (for success, loading and errors).