CDierolf

CDierolf

Passing a livestream to a component/live_component issue

Hello,

I’ve created a stream in a parent liveview that I want passed to a live_component. On the parent, when I create the stream:

    socket
    |> stream(:my_stream, [])
    |> tap(fn x -> IO.inspect(x.assigns) end)

The stream is placed under the streams key in the sockets assigns as indicated:

  streams: %{
    __changed__: MapSet.new([:medications]),
    my_stream: %Phoenix.LiveView.LiveStream{
      name: :medications,
      dom_id: #Function<3.112696910/1 in Phoenix.LiveView.LiveStream.new/4>,
      ref: "0",
      inserts: [],
      deletes: [],
      reset?: false,
      consumable?: false
    },
    __configured__: %{},
    __ref__: 1
  },

However, the minute I attempt the assign that stream to the list of assigns for a component or a live component:

Component:

    <.form_step
      form={@current_form}
...
      my_stream={@streams.my_stream}
...
    />

Live Component:

           <.live_component
              module={Web.Live.Common.StreamTest}
              id="med-search-id"
              my_stream={@my_stream}
            />

The stream is now in the assigns as:

  my_stream: %Phoenix.LiveView.LiveStream{
    name: :my_stream,
    dom_id: #Function<3.112696910/1 in Phoenix.LiveView.LiveStream.new/4>,
    ref: "0",
    inserts: [],
    deletes: [],
    reset?: false,
    consumable?: false
  },

This all makes sense to me. After all I’m literally assigning the stream into the assigns.
This issue comes into play when I attempt to call stream_insert/4. The stream is no longer in socket.assigns.stream, it’s in socket.assigns. So the call to stream_insert fails:

** (KeyError) key :streams not found in: %{
  id: "med-search-id",
  __changed__: %{med_search_list: true, med_search_loading: true},
  flash: %{},
  myself: %Phoenix.LiveComponent.CID{cid: 1},
  my_stream: %Phoenix.LiveView.LiveStream{
    name: :my_stream,
    dom_id: #Function<3.112696910/1 in Phoenix.LiveView.LiveStream.new/4>,
    ref: "0",
    inserts: [],
    deletes: [],
    reset?: false,
    consumable?: false
  },

My situation revolves around a live component so my work around is to just assign a regular list in the live_view, and in the live_component declare a stream. BUT since I’m maintaining the sources-of-truth’s in the live_view, I have to update both the stream AND regular list. The regular list being the source of truth for which I can do things to, and the stream for displaying the source of truth (because I can’t access the stream in the parent live view.)

    new_state =
      state
      |> Map.put(:id, Ecto.UUID.generate())

    socket
    |> stream_insert(:my_stream, new_state)
    |> update(:my_list_for_stream_in_live_component, fn states ->
      [new_state | states]
    end)

Seems hacky and probably unnecessary. This this not the intended purpose of streams? Am I missing something trying to get a stream into a component/live component? Should I just keep to the temporary_assigns and phx-update=“append” method for things like this?

Most Liked

LostKobrakai

LostKobrakai

Why should a child component be allowed to insert items in a stream defined in a parent? If the parent is the source of truth then the children are not supposed to fiddle with that.

Last Post!

CDierolf

CDierolf

Decent point-could be an improvement opportunity as this is probably more of an I’m-in-the-weeds situation architecturally and I think I needed that pointed question to discover the design flaw :duck:

Where Next?

Popular in Discussions Top

PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
Crowdhailer
I’ve been hearing much about the new formatter and it’s something I have been keen to try. I find examples buy far the most illuminating...
248 19740 150
New
tmbb
This is a post to discuss the new Phoenix LiveView functionality. From Chris’s talk, it appears that they generate all HTML on the serve...
342 18584 126
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
Fl4m3Ph03n1x
Background A few days ago I was listening to The future of Elixir from Elixir Talks, with Dave Thomas (@pragdave ) and Brian Mitchell. I...
New
nunobernardes99
Hi there Elixir friends :vulcan_salute: In a recent task I was on, I needed to check in two dates which of them is the maximum and which...
New
matthias_toepp
I’d love to hear what people think about Wisp, the new Gleam web framework started by Gleam’s primary creator Louis Pilfold. Gleam, alon...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 49084 226
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement