dakora

dakora

Communicating Between Live Components

Hello all!

I’ve been working a few days on trying to solve a relatively simple issue, however it’s turning into quite the road block. I have a Live Component. which is nested inside of a Form Component which I’ve used to replace a custom AJAX search box which was dreadful to use and consisted of 400 lines of javascript.

I’m having an issue attempting to reconstruct part of the functionality, which basically involves copying the value in short to a related sibling search box if it happens to be empty.

I’ve had little luck so far in getting the two Live Components to talk to each other without causing a mess.

The first idea i had was to use Phoenix PubSub, but discovered live components can’t have handle info, so that goes to the parent, which is fine. I decided to try the more direct route, and use send/2 which gets my message to the parent however it looks like the only option is send_update/2 to get anything to a child liveview.

That won’t work because calling update wipes out all of the existing assigns for the component, and there is no way to get the originals back to it (as its a different component thats requesting the update). Back to square one!

I’m not terribly familiar with send/2, however that could be another avenue to explore. I don’t really see anyway to let the requesting component know which process it needs to send to. I tried backtracking through the Live Component code for send_update, but it does a weird thing with the Phoenix Channel and it doesn’t look obvious how it actually triggers update on the correct component by ID.

What are the other options for communicating between Live Components? The less desirable I can think of would be to fire up full blown Live Views for every search box, but that seems too heavy for one input and some basic search functionality.

Most Liked

sfusato

sfusato

I usually have a simple public API for each component that needs to be talked to. Something like:

defmodule LiveComponentTwo do
  ######### Public API
  def update_text(id, text) do
    send_update(__MODULE__, id: id, update: :update_text, text: text)
  end
  #########

  def update(%{update: :update_text, text: text}, socket) do
    # I suppose here you could check if the value in the socket is empty
    {:ok, assign(socket, :text, text)}
  end

  def update(assigns, socket) do
    {:ok, assign(socket, assigns)}
  end
end

then, LiveComponentTwo.update_text("id_of_the_component", "text")

Notice that I add a key update: :update_text and then pattern match on that key in the update callback.

sfusato

sfusato

It’s cleaner this way, easier to refactor, it’s obvious that this component is called from outside just by opening the file.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

This shouldn’t be true, are you using stateless or stateful components? To do the kind of communication you want you definitely need stateful live components, and in those cases update does not clobber existing assigns.

Where Next?

Popular in Questions Top

minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 131117 1222
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31586 112
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New

We're in Beta

About us Mission Statement