phoenixframework / phoenix_live_view

Rich, real-time user experiences with server-rendered HTML
https://hex.pm/packages/phoenix_live_view
MIT License
6.18k stars 931 forks source link

Regression in 0.20 when resetting a stream that contains the same values, but reordered. #2826

Closed Malian closed 1 year ago

Malian commented 1 year ago

Environment

Actual behavior

With the previous version of Phoenix Live View (0.19.5), when I reset a stream with stream(socket, :my_stream, values, reset: true) in handle_params or handle_event where values are the same as the previous stream but reordered, the stream was reinitialized. It is useful with a table when you order by a column (asc/desc).

With the latest version of Phoenix Live View (0.20.0), the stream is not reset, and the table does not change.

Here is the code that reproduces the behaviour. Below, you will find the simple app that reproduces the bug.

defmodule StreamResetWeb.ResetStreamLive do
  use StreamResetWeb, :live_view

  @users [
    %{id: 1, name: "John", age: 27},
    %{id: 2, name: "Mary", age: 25},
    %{id: 3, name: "Peter", age: 30}
  ]

  def handle_params(_params, _uri, socket) do
    new_stream =
      @users
      |> Enum.shuffle()
      |> IO.inspect(label: "New stream (patch)")

    socket =
      socket
      |> stream(:users, new_stream)

    {:noreply, socket}
  end

  def render(assigns) do
    ~H"""
    <.button phx-click={JS.patch(~p"/reset_stream")}>
      Shuffle (patch)
    </.button>

    <.table id="users" rows={@streams.users}>
      <:col :let={{_id, user}} label="id"><%= user.id %></:col>
      <:col :let={{_id, user}} label="name"><%= user.name %></:col>
      <:col :let={{_id, user}} label="age"><%= user.age %></:col>
    </.table>
    """
  end
end

Here is a working application (0.19.5): https://github.com/Malian/stream_reset_bug Here is the application upgraded to Phoenix Live View (0.20.0): https://github.com/Malian/stream_reset_bug/pull/1

Expected behavior

The stream has been reset.

Malian commented 1 year ago

For those who wants to upgrade to 0.20, here's a workaround that works for me. In my case, I know that all the elements are present on the page, so deleting and adding each element "solves" the problem.

socket
|> then(fn socket ->
  Enum.reduce(items, socket, fn item, socket ->
    socket
    |> stream_delete(:items, item)
    |> stream_insert(:items, item)
  end)
end)

However, this won't work on pages where I use pagination. Not sure how to quickly fix this without tracking the items on the page.

SteffenDE commented 1 year ago

We stumbled across this as well trying to update to LV 0.20.1 from 0.19.5. We rely on reset: true for rendering paginated, sortable tables. Staying on 0.19 for now.

chrismccord commented 1 year ago

Closed via https://github.com/phoenixframework/phoenix_live_view/commit/ddccaa6b63559389eeea9edd388c718421ab53cc

chrismccord commented 1 year ago

Thanks!

Malian commented 1 year ago

I can confirm the commit fixes this issue. Thanks ! :heart:

cheerfulstoic commented 11 months ago

I seem to be having an issue with reset: true with infinite scroll where the page doesn't get reset when I change filter options for my query. Instead it seems to append the results to the next page.

I might be able to reproduce it later, but I was able to confirm that the problem exists on 0.20.1 and with {:phoenix_live_view, git: "https://github.com/phoenixframework/phoenix_live_view.git"}, (which I believe should be main), but the problem goes away when I downgrade to 0.19.5.

ivank commented 10 months ago

I was able to replicate this with normal pagination as well (offset/limit) downgrading back to 0.19.5 also solved the issue for me thanks!

Malian commented 10 months ago

@ivank the version 0.20.2 should solve this issue.

barkerja commented 10 months ago

@ivank the version 0.20.2 should solve this issue.

I've confirmed I still see the issue in 0.20.2

sodapopcan commented 9 months ago

I'm having an issue with regular old offset pagination and filtering. It remembers the positions of the filtered elements and they stick around when filters are reset.

For example, consider this list:

If I filter on "Hello" the results are:

And when reseting the filters, which also does a stream reset, I get:

This does not happen on 0.19.x.

SteffenDE commented 9 months ago

@sodapopcan https://github.com/phoenixframework/phoenix_live_view/pull/2969 should fix this