How to update/reassign a list on a LiveView stream that was previously assigned on handle_params function?

Example:

defmodule LiveViewWeb.Orders do
 def mount(_params, _session, socket) do
 end

 def handle_params(params, _uri, socket) do
   page = params["page"]
   per_page = params["per_page"]
  
  orders = Order.list(page, per_page)
  socket = socket |> assign(page: page, per_page: per_page) |> stream(:orders, orders)
 end
end

So, based on the per_page and page parameters the orders list is updated.
However, in the log file I am getting this error when I click on a page button: “ArgumentError existing hook :orders already attached on :after_render”.

I’m not sure If I should go back to using temporary_assigns instead of stream api. Perhaps, I shouldn’t use streams for this kind of case :thinking:

2 Likes

It’s now my obligation to quote this, as I’m getting more and more excited:

2 Likes

I read the other thread but I’m not sure I understood what’s the workaround for this at the moment. The docs weren’t clear to me either. Let’s say I have a route for displaying a blog post where users can:

  • View the blog post.
  • Edit the blog post using a modal.
  • List all comments for this blog post.

The LiveView generator gives me following code:

@impl true
def handle_params(%{"id" => id}, _, socket) do
  {:noreply,
   socket
   |> assign(:page_title, page_title(socket.assigns.live_action))
   |> assign(:post, Blog.get_post!(id))}
end

Now I want to use stream/4 to display a list of comments. I’ve updated handle_params/3 to do it:

def handle_params(%{"id" => id}, _, socket) do
  {:noreply,
   socket
   |> assign(:page_title, page_title(socket.assigns.live_action))
   |> assign(:post, Blog.get_post!(id))
   |> stream(:comments, Blog.get_comments_by_post_id(id))}
end

The code above runs fine until a open the generated modal (:edit live_action) for editing the blog post. When I open it, I get that “ArgumentError existing hook :comments already attached on :after_render”.

Do I need to remove all comments using stream_delete and add them again using stream_insert?

This repo has an example of what I mean. Go to localhost:4000/posts/1 and click on the “edit” button.