Update the query string in Phoenix Liveview

Hi all,

in a handle_event function I would like to perform a push_patch appending something to the current querystring.

How can I do that?

I see that handle_params is executed after every push_patch, but that is too late for my goal?

Thank you

Use the to option of push_patch and add the params to the route.

I am doing something like:

@impl true
def handle_event("sort", %{"sort_form" => %{"by" => sort_params}}, socket) do
  {:noreply,
   socket
   |> assign(:page, load_page(%{"sort" => [sort_params]}))
   |> push_patch(to: ~p"/admin/workshops?sort[]=#{sort_params}")}
end

As you can see I am overwriting the querystring.

Should I keep the map of params in the assigns, update that and put that alltogheter in the sigil?

Thank you

The updated version to keep track of the existing params is

@impl true
def handle_event("sort", %{"sort_form" => %{"by" => sort_param}}, socket) do
  params = Map.put(socket.assigns.qs, "sort", [sort_param])

  {:noreply,
   socket
   |> assign(:page, load_page(params))
   |> assign(:qs, params)
   |> push_patch(to: ~p"/admin/workshops?#{params}")}
end

:qs is the map holding the params, is this ok or am I off track here?

Cheers

I think you should assign the params from the query string in the socket.

@impl true
def handle_params(params, _url, socket) do

  {:noreply, assign(socket, :params, params)}
end

then in your handle_event/3

@impl true
def handle_event("sort", %{"sort_form" => %{"by" => sort_params}}, socket) do
  existing_params = socket.assigns.params

  {:noreply,
   socket
   |> assign(:page, load_page(%{"sort" => [sort_params]}))
   |> push_patch(to: ~p"/admin/workshops?#{Map.merge(existing_params, sort_params)}")}
end

For example if I have a query string like this: "/projects/?sort_by=name&sort_order=asc&page=1&per_page=10"

@impl true
def handle_params(params, _url, socket) do

  sort_options = %{
    sort_by: params["sort_by"] || "name"
    sort_order: params["sort_order"]
  }

paginate_options = %{
    page: params["page"] || "1"
    per_page: params["per_page"] || "20"
  }

  projects = list_projects(sort_options, paginate_options)

  socket =
    assign(socket,
      paginate_options: paginate_options,
      sort_options: sort_options,
      projects: projects
    )

  {:noreply, socket}
  end

Then if you receive an event with sorting params for example:

@impl true
def handle_event("select_sort_order", %{"sort_order" => sort_order}, socket) do
 paginate_opts = socket.assigns.paginate_options
 existing_sort_opts = socket.assigns.sort_options

 new_sort_opts = %{existing_sort_opts | sort_order: sort_order}

 {:noreply,
   push_patch(socket, to: ~p"/projects/?#{Map.merge(paginate_opts, new_sort_opts)}")}
end
5 Likes