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:
- You will have to store the uri in assigns.
- You will also need to convert the
extraarg into a string map to correctly merge into the parsed query params, which will be string keys. This is represented by a utility functionto_string_map/1which simply does a list comprehension to convert the atom key to a string. - You will need to filter out empty string values if
extracontains a nil value. - You will need to check if the encoded params is an empty string, and if so, set the
:querykey of the newURIto nil. This new%URI{}struct needs all keys except:pathto be replaced with nil.






















