"push_patch" won't update URL

I have a component for pagination. It works but there’s one issue: it won’t replace or update the URL in the browser dynamically. Namely, when I change a page – 2nd, 3rd, 4th page of the data in a table – I want the URL to get updated as well: updated in the browser URL bar and appended to the browser history.


But at the moment only data will get fetched correctly, according to the current page, whereas the URL will remain static always - my_domain.com/my/pigs:

  @impl true
  def handle_info({:update, opts}, socket) do
    extra_params = merge_and_sanitize_params(socket, opts)
    path = "/my/pigs"
    to = path <> "?" <> URI.encode_query(extra_params)

    # socket = push_patch(socket, to: to, replace: true)
    socket = push_patch(socket, to: to)

    {:noreply, socket}

I’ve tried replace with true, and without – the URL will stay “my/pigs” no matter what.

The _url in handle_params(..) will contain the correct one – with ?page=X&page_size=Y which is correct:

  @impl true
  def handle_params(params, _url, socket) do
    # _url will contain dynamic url, with the correct params
    # .....

However, the the URL in browser the will still remain static.

What’s the matter?

How about

socket = push_patch(socket, to: ~p"/my/pigs?#{extra_params}")

Why? to already will contain that – URL with the correct query string.

I don’t think handle_info is the best callback to handle this job.

Live navigation is setup specifically for the use case you are describing.

Here’s a section of the documentation using pagination as an example:

For example, imagine you have a blog. The URL for a single post is: “/blog/posts/:post_id”. In the post page, you have comments and they are paginated. You use <.link patch={...}> to update the shown comments every time the user paginates, updating the URL to “/blog/posts/:post_id?page=X”. In this example, you will access "post_id" on mount/3 and the page of comments on handle_params/3.

It may not be the best one. I need to find the source of the issue rather than the best callback, though.

Here’s a part of my pagination component

      <div class="page-stepper">
        <%= for {page_number, current_page?} <- pages(@pagination) do %>
          <div phx-click="show_page"
            class={if current_page?, do: "active"}
          ><%= page_number %></div>
        <% end %>


# ...........
  def handle_event("show_page", params, socket) do
    # ..........
    # opts ---> page, page_size
    send(self(), {:update, opts})
    {:noreply, socket}
    # ........
1 Like