2

In my Phoenix application, I want to add a query string to a URL:

some_cool_path(@conn, :index, "view-mode": "table")

I expected that it would generate a URL like /some_cool?view-mode=table, but instead it throws an exception:

protocol Phoenix.Param not implemented for ["view-mode": "table"]

How do I fix that?

Sheharyar
  • 73,588
  • 21
  • 168
  • 215
Jodimoro
  • 4,355
  • 3
  • 11
  • 18
  • Can you post the router code where you've defined this route? – Dogbert May 08 '17 at 01:11
  • @Dogbert, just an ordinary route `get "some_cooll", Controller1, :action1` – Jodimoro May 08 '17 at 01:15
  • Your code is correct if you've got the controller and action names right. That error message indicates that the route actually has a mandatory parameter in the URL. `post_path(MyApp.Endpoint, :index, "view-mode": "table") #=> "/posts?view-mode=table"`. Can you paste the exact line in the router that generates `some_cool_path` helper? – Dogbert May 08 '17 at 01:22
  • @Dogbert, no problem, I've fixed it. – Jodimoro May 08 '17 at 01:26
  • Are you sure about that? If you manually encoded the query and passed like the answer below you're probably getting `/some_cool/view-mode=table`, i.e. not a query string. – Dogbert May 08 '17 at 01:28

1 Answers1

6

To build a query string from a Keyword List, you can use URI.encode_query/1:

iex(1)> URI.encode_query("view-mode": "table")
"view-mode=table"

But that doesn't seem to be the problem here. If your route has some required parameters, you need to specify all of them before passing the query Keyword List.

For Example:

  • If your route is something like /users, your code above would work.
  • But if it has a required parameter like /users/:id, you first need to pass the required argument(s) before specifying the Keyword List for the query string. So for this, you should call something like this:

    users_path(@conn, :show, @user.username, "view-mode": "table")
    
Sheharyar
  • 73,588
  • 21
  • 168
  • 215
  • thanks. one more question: suppose I had an url with an "#" --> `example.com/something#as_table` or `example.com/something#as_chart`. How would I do pattern match on or deconstract it in a controller in an action? Meaning, it want to get the value after the `#` – Jodimoro May 08 '17 at 01:13
  • It's called an Anchor or Fragment and it's not available on the serverside, only client-side. [See this answer](http://stackoverflow.com/questions/34687098/how-to-get-the-fragment-identifier-part-of-an-url). – Sheharyar May 08 '17 at 01:17