Why you say unfortunately
? The LiveComponent lives in the same LiveView process. If you need to make async db calls, you could make the db call from the component and then handle the async response in the LiveView module (since it’s the same process), which then updates the data passed to the component (or just calls send_update
with the new data).
Something like
defmodule SampleWeb.FormComponent do
use SampleWeb, :live_component
def update ...
def render...
def handle_event("submit", _, socket) do
Sample.async_db_call( self() ) #makes an async call which will send back the data to self()
socket = assign(socket, :status, :validating)
{:noreply, socket}
end
end
defmodule SampleWeb.PageLive do
use SampleWeb, :live_view
...
def handle_info({:async_db_call_response, data}, socket) do
# do something with the data
send_update SampleWeb.FormComponent, id: "form", ...
{:noreply, socket}
end
end
Another way can be that the component sends a message to the LiveView process (self()
) just asking to make the async db call. The LiveView process then makes the call, receives the result and updates the data passed to the component. Something like this:
defmodule SampleWeb.FormComponent do
use SampleWeb, :live_component
def handle_event("submit", event, socket) do
send(self(), {:form_submit, event})
socket = assign(socket, :status, :validating)
{:noreply, socket}
end
end
defmodule SampleWeb.PageLive do
use SampleWeb, :live_view
def handle_info({:form_submit, event}) do
Sample.async_db_call()
{:noreply, socket}
end
def handle_info({:async_db_call_response, data}, socket) do
# do something with the data
send_update SampleWeb.FormComponent, id: "form", data: data
{:noreply, socket}
end
end
In general, the async messages (like async db response etc.) are handled by the LiveView module with the handle_info
callback.
Do you really need a component? You could start by making it work with a single LiveView, and then move some parts to a component.
Can you please post the LV and component code you are working on?