ream88

ream88

Customize params for LiveViews

Hello,

I’m currently facing a challenge with my Phoenix app, which displays statistics about the products we support. I’m extending its functionality to allow users to specify a date range route parameter to filter the statistics. My goal is to define /stats and /stats/:range in my router.

However, I already have a /stats/:country route that takes a two-character ISO country code, such as /stats/AT for Austrian statistics.

  live "/stats", StatisticsLive.General
  live "/stats/:country", StatisticsLive.ByCountry
  live "/stats/:range", StatisticsLive.General

These two routes now conflict with each other, and I can’t define constraints like in Rails using the :constraints option (at least that I know of).

I now tried the following, because I have a fixed list of countries:

  live "/stats", StatisticsLive.General

  for country <- Countries.all() do
    live "/stats/#{country}", StatisticsLive.ByCountry, String.to_existing_atom(country)
  end

  live "/stats/:range", StatisticsLive.General

This works by misusing the live_action value passed to the LiveView. However, I need to convert the values to atoms back and forth, can’t access the value via the params map, don’t see it in logs, and overall, it just doesn’t feel right.

Is there a reason why this syntax isn’t currently supported?

  for country <- Countries.all() do
    live "/stats/#{country}", StatisticsLive.ByCountry, params: %{country: country}
  end

I don’t want to introduce a custom plug for this, as it reduces the clarity and visibility of my routes.

Most Liked

KP123

KP123

Am I correct in assuming that the resource is “stats” and that country and range is just a filter over those resources? If so then use a query parameter. Something like /stats?country=us&range=1-5

Edit: This has the benefit of allowing the user to select a range in a specific country instead of one or the other

sodapopcan

sodapopcan

What’s the usecase for wanting URLs like this? Is there a big difference between ByCountry and General? Otherwise, filters like these are exactly what query parameters are for.

KP123

KP123

I’d still use query params for this. Instead of range I’d use from. Then you can have ranges displayed like so:

  • Range of days: /stats?from=2024-20-06&to=2024-30-06
  • A specific day: /stats?from=2024-30-06&to=2024-30-06
  • Special case values: /stats?from=yesterday

And of course every filter you dream up in the future just works /stats?from=today&country=fr&future-filter=arg

You could even do /stats?yesterday. Paths are for hierarchical data, query params for key-value data

sodapopcan

sodapopcan

Routes are compiled so I don’t think something like Rails’ regex-based constraints could ever be possible. I also don’t see a big difference between params: %{country: country} and your live action approach.

I agree with @thiagomajesk that having sub routes is the way to go, but if you really don’t want to, I would make live components for each stat type and delegate in the router:

def render(%{param: param} = assigns) when param in @countries do
  ~H"""
  <.live_component id="countries" module={MyAppWeb.CountryStatsComponent} countries={@countries} />
  """
end

def render(assigns) do
  ~H"""
  <.live_component id="range" module={MyAppWeb.RangeStatsComponent} ranges={@ranges} />
  """
end

That’s just a high-level example and I’m leaving out some context—there are several ways you could accomplish this.

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement