0

Is there a way to trigger a re-render with an updated state multiple times from a handle_event call?

Here's some vague idea of what I'm trying to do:

def handle_event("button_clicked", %{button: which_button}, socket) do
  send_a_reply_before_finishing_your_work(assign(socket, :working, true))
  BigLongTask.run(which_button)
  {:noreply, socket} # working: false here
end

So that in my heex, I can toggle a spinner:

<div :if={!@working}>
  <.button1 phx-click="clicked" phx-value-button="button1" />
  <.button2 phx-click="clicked" phx-value-button="button2" />
</div>

<.spinner :if={@working} />

I looked at using phx-click-loading css to trigger this, but that's limited in scope to the current button being clicked. Here, I'm replacing a parent container of the button instead.

I also looked at LiveView.send_update/3, which seems like exactly what I'd want, but that's designed to send a message to a component attached somewhere within the Live View. Wrapping up the two buttons into a dedicated component certainly is possible but seems like overkill for what I'm trying to accomplish.

Thanks

voxobscuro
  • 2,132
  • 1
  • 21
  • 45

1 Answers1

2

It seems like I was really close with send_update/3, but the actual solution was to just use Process.send/3:

def handle_event("button_clicked", socket) do
  send(self(), :start_the_long_running_task_please)
  {:noreply, assign(socket, :working, true)}
end

def handle_info(:start_the_long_running_task_please, socket) do
  BigLongTask.run()
  {:noreply, assign(socket, :working, false)}
end
voxobscuro
  • 2,132
  • 1
  • 21
  • 45