LiveView push_patch append to params

for whoever that comes across this thread, @josevalim’s answer will not apply if you are using actions in your router declarations, as the route helper gets renamed to match the controller, and also results in different helper arities for different helpers.

Until the day comes where where we can use Phoenix.Controller helpers like current_path/2 to merge in params in liveview, you’ll have to update the URI manually.

You will need to modify step 2 of @josevalim’s answer to something like this:

def self_path(socket, extra) do
      # explained in notes 1
  uri = URI.parse(socket.assigns.uri)

    current_query_params =
      (uri.query || "")
      |> URI.decode_query()

    # explained in notes 2
    to_merge = Enum.into(extra, %{}) |> to_string_map()

    new_query_params =
      current_query_params
      |> Map.merge(to_merge)
      # explained in notes 3
      |> Enum.filter(fn {_k, v} -> v != "" end)

    encoded_params = URI.encode_query(new_query_params)

    %URI{
      uri
      | authority: nil,
        host: nil,
        scheme: nil,
        port: nil,
      # explained in notes 4
        query: if(encoded_params == "", do: nil, else: encoded_params)
    }
    |> URI.to_string()

end

Note that:

  1. You will have to store the uri in assigns.
  2. You will also need to convert the extra arg into a string map to correctly merge into the parsed query params, which will be string keys. This is represented by a utility function to_string_map/1 which simply does a list comprehension to convert the atom key to a string.
  3. You will need to filter out empty string values if extra contains a nil value.
  4. You will need to check if the encoded params is an empty string, and if so, set the :query key of the new URI to nil. This new %URI{} struct needs all keys except :path to be replaced with nil.