-
Notifications
You must be signed in to change notification settings - Fork 893
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
Stream reset doesn't work when changing record filter #2895
Comments
I can confirm I have the same issue here. My case is a stream of events with event filters. When I load the page all the events are rendered. When I click a filter, which removes some events from the stream it works as expected. But when I remove the filter I expect the list to return to the previous state, but it appends the events that have re-appeared to the bottom of the list instead of in the position they are in the stream. I'm using Main [@dfcdb18] also doesn't work for me and can also confirm that it behaves as expected in LV 0.19.5. |
I have the exactly same situation @moomerman described. Tried use master branch - did not help. |
Same here, also created an isolated case using a simple table with numbers. |
Yep, seeing the same issue as @moomerman using the latest main. I have a table with a list of elements like this |
Feel like a race condition somewhere. Anyway I solved my problem by defer sending new results ...
def apply_action(socket, :index, params) do
Process.send_after(self(), {:list, params}, 100);
# clear existing items
socket |> stream(:items, [], reset: true)
end
...
def handle_info({:list, params}, socket) do
# perform search/filtering
new_items = [....]
{:noreply, socket |> stream(:items, new_items)}
end |
It isn't a race condition since everything is serialized, probably just an issue with the order of the operations! |
@moomerman Updating to release |
The fix in #2969 doesn't fix the bug I reported in this issue, I've created this single file reproduction of my issue:
Application.put_env(:sample, Example.Endpoint,
http: [ip: {127, 0, 0, 1}, port: 5001],
server: true,
live_view: [signing_salt: "aaaaaaaa"],
secret_key_base: String.duplicate("a", 64)
)
Mix.install([
{:plug_cowboy, "~> 2.5"},
{:jason, "~> 1.0"},
{:phoenix, "~> 1.7.10", override: true},
{:phoenix_live_view, github: "phoenixframework/phoenix_live_view", branch: "main"}
])
defmodule Example.ErrorView do
def render(template, _), do: Phoenix.Controller.status_message_from_template(template)
end
defmodule Example.HomeLive do
use Phoenix.LiveView, layout: {__MODULE__, :live}
def mount(_params, _session, socket) do
socket
|> stream(:items, [
%{id: "a", name: "A"},
%{id: "b", name: "B"},
%{id: "c", name: "C"},
%{id: "d", name: "D"}
])
|> then(&{:ok, &1})
end
def render("live.html", assigns) do
~H"""
<script src="https://cdn.jsdelivr.net/npm/phoenix@1.7.10/priv/static/phoenix.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/phoenixframework/phoenix_live_view@main/priv/static/phoenix_live_view.js"></script>
<script>
let liveSocket = new window.LiveView.LiveSocket("/live", window.Phoenix.Socket)
liveSocket.connect()
</script>
<style>
* { font-size: 1.1em; }
</style>
<%= @inner_content %>
"""
end
def render(assigns) do
~H"""
<ul phx-update="stream" id="thelist">
<li id={id} :for={{id, item} <- @streams.items}>
<%= item.name %>
</li>
</ul>
<button phx-click="filter">Filter</button>
<button phx-click="reset">Reset</button>
"""
end
def handle_event("filter", _, socket) do
{:noreply,
stream(
socket,
:items,
[
%{id: "b", name: "B"},
%{id: "c", name: "C"},
%{id: "d", name: "D"}
],
reset: true
)}
end
def handle_event("reset", _, socket) do
{:noreply,
stream(
socket,
:items,
[
%{id: "a", name: "A"},
%{id: "b", name: "B"},
%{id: "c", name: "C"},
%{id: "d", name: "D"}
],
reset: true
)}
end
end
defmodule Example.Router do
use Phoenix.Router
import Phoenix.LiveView.Router
pipeline :browser do
plug(:accepts, ["html"])
end
scope "/", Example do
pipe_through(:browser)
live("/", HomeLive, :index)
end
end
defmodule Example.Endpoint do
use Phoenix.Endpoint, otp_app: :sample
socket("/live", Phoenix.LiveView.Socket)
plug(Example.Router)
end
{:ok, _} = Supervisor.start_link([Example.Endpoint], strategy: :one_for_one)
Process.sleep(:infinity) |
@moomerman, moved to #2994. |
Environment
Elixir 1.14.5 (compiled with Erlang/OTP 25)
1.7.9
0.20.1
Actual behavior
I created this app to reproduce the issue: https://github.com/cheerfulstoic/live_view_reset_reproduction
It's using infinite scrolling. I start off with no records and two empty checkboxes. Each time the checkboxes are changed,
reset: true
is given. When checking one checkbox the correct records appear. When checking the second checkbox the original records aren't replaced with the new ones (showing records intermixed), but they are instead appended to the end of the list.The issue isn't there using
phoenix_live_view
version 0.19.5Expected behavior
Records should refresh instead of appending.
Following up from this comment: #2826 (comment)
The text was updated successfully, but these errors were encountered: