Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document edge case that causes stream_insert to insert a duplicate. #3596

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion lib/phoenix_live_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1864,7 +1864,13 @@ defmodule Phoenix.LiveView do
As shown, an existing item on the client can be updated by issuing a `stream_insert`
for the existing item. When the client updates an existing item, the item will remain
in the same location as it was previously, and will not be moved to the end of the
parent children. To both update an existing item and move it to another position,
parent children.

One exception to this is if you call `stream` with a collection of items in your `mount` function,
and then `stream_insert` an updated item that was previously streamed in your `handle_params` function.
You will end up with a duplicate item.
Comment on lines +1869 to +1871
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
One exception to this is if you call `stream` with a collection of items in your `mount` function,
and then `stream_insert` an updated item that was previously streamed in your `handle_params` function.
You will end up with a duplicate item.
> #### A note on duplicates, streams and the LiveView life-cycle {: .info}
> LiveView does not support updating an already streamed item during in same render cycle.
> This can affect you in the following ways:
>
> * If your list of items passed to `stream/4` already contains duplicates,
> these duplicates will end up on the page. You'll need to deduplicate them before calling `stream/4`.
> * Due to the life-cycle of a LiveView, if you call `stream/4` with a list of items in
> your `c:mount/3` callback, you cannot use `stream_insert/4` in `c:handle_params/3`
> to update an item that was already inserted in `c:mount/3`. As there is no render in between
> those two callbacks on the initial mount, you would end up with a duplicate item in the stream.
> You can work-around this limitation by setting an "initial_mounted" assign in `c:mount/3`
> and pattern-match on this flag in `c:handle_params/3` to handle the different cases.

cc @josevalim


To both update an existing item and move it to another position,
issue a `stream_delete`, followed by a `stream_insert`. For example:

song = get_song!(id)
Expand Down