shahryarjb
How to add Map in phoenix conn's params in Plug
hello, I need to add some Map in phoenix conn’s params in Plug
for example :
def init(_params) do
end
def call(%Plug.Conn{params: %{"ptoken" => ptoken}} = conn, params) do
outputs = case Guardian.decode_and_verify(ptoken) do
{:ok, _climes} ->
# I need to add it in blow conn , map like : %{"last_ip" => "127.1.2.3"}
assign(conn, :user_ip_checked, params)
{:error, _ms} ->
conn
|> put_status(403)
|> json(%{error_code: "403", error_msg: "You don't have an access."})
|> halt()
end
outputs
end
how can I do this ?
Marked As Solved
peerreynders
The idea is not to subvert the intent behind Plug.Conn.params - it’s not a general data “dumping ground” - that is Plug.Conn.assigns job. So the strategy would be to put the information in Plug.Conn.assigns first and then combine it in the last possible moment. So start with
{:ok, climes} ->
conn =
conn
|> assign(:all_req, %{"last_ip", "#{climes["ip"]}"})
|> assign(:user_ip_checked, params)
And then have a helper function that assembles everything
def make_all_req(conn, params) do
conn.assigns
|> Map.get(:all_req, %{})
|> Map.merge(conn.params)
|> Map.merge(params)
end
which you can use at the last possible moment, like:
def get_posts_category(conn, %{"seo_alias_link" => _seo_alias_link, "page_number" => _page_number, "page_size" => _page_size, "token" => _token, "ptoken" => _ptoken} = params) do
all_req = make_all_req(conn, params)
...
end
You really shouldn’t be sending the entire contents of the Plug.Conn structure.
- The actual content may change in the next version of
Plug.Conn - The organization of the
Plug.Connstructure could change in the next version - By using
Plug.Connverbatim you are unnecessarily coupling other parts of your system to it (and the version that you started using).
In the interest of decoupling:
- Decide what minimal information is actually useful.
- Structure that information in a way the makes sense to your system. Your information structure has different reasons to change than those that will force a change on
Plug.Conn.
Also Liked
peerreynders
Yes but action functions receive 2 parameters:
def index(conn, params) do
...
end
assigns- shared user data as a map
So rather than polluting Plug.Conn.params with non-standard data, you should use Plug.Conn.assigns which is intended for “user data”, e.g.:
{:ok, climes} ->
conn
|> assign(:last_ip, "#{climes["ip"]}")
|> assign(:user_ip_checked, params)
and then inside the action function retrieve it:
def index(conn, params) do
...
last_ip = conn.assigns[:last_ip]
...
end
kokolegorille
Given that conn is a struct, I would update it like this…
conn = %{conn | assigns: Map.merge(conn.assigns, %{"last_ip" => "127.1.2.3"})}
BTW It really depends what You want to do with assigns, You could use Map.update, or Map.merge or anything You need depending on situation.
With Map.update…
args = %{"last_ip" => "127.1.2.3"}
conn = Map.update(conn, :assigns, args, &Map.merge(&1, args))
shahryarjb
Thanks , I edited your code and now it works for me
code :
conn = %{conn | params: Map.merge(conn.params, %{"last_ip" => "#{climes["ip"]}"})}
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









