WFransen
Best practice use data in javascript (thus passing data)
Haven’t found a topic on the elixir forum regarding this, only on stackoverflow. If it exists already, please point me in the right direction and I’ll delete this post. Because the response was limited, I was wondering if the Phoenix experts here could provide their opinions regarding passing data from the controller to your JS.
A use case that I’m facing now:
Building a timeline-ish feature with an edit page. On the edit page, i want to let the user upload images asynchronously. (so that if they edit something in the text field, the explanation on the timeline, and then upload an image it doesn’t need to refresh) But I need the article id to make the asynchronous call.
As far as i know there are 2 options:
- work with data attributes (link)
- put a tag in your template, and assign a variable where you put your json encoded (elixir) variable so that you can access it in your javascript.
This is a problem with multiple frameworks, and I’d be truly happy if some sort of best-practice could be formed.
Thank you in advance!
Most Liked Responses
kokolegorille
I prefer to pass data to js with data attributes, it’s easy.
I have something like this in my template
<div
id="app"
data-src="<%= display_path @picture, :large %>"
data-id="<%= @picture.id %>"
data-token="<%= @token %>"></div>
and I retrieve like this in app.js.
const root = document.getElementById('app');
if (root) {
const { src, id, token } = root.dataset;
console.log(src, id, token);
}
kokolegorille
Hello and welcome,
It is a little bit more complicate to pass js data to the server, because http is not bidirectional.
Are You sure You cannot do all client side? recently I had to display datetime in the browser timezone. It was simpler to add some class to datetime container (“utc_to_local”) and make the change client side only.
But if You want to make it server side, I think the easiest solution would be to pass the locale, like new?locale=whatever. Because new is a get request.
You could use a plug to set a session_id.
This way, You could pass data to the server with this session_id, and retrieve this data server side
It’s not even needed, and it is nice to see how it is done in liveview, which use websocket under the hood. You can set params to the socket, and retrieve them in liveview.
let liveSocket = new LiveSocket("/live", Socket, {
params: {
_csrf_token: csrfToken,
locale: Intl.NumberFormat().resolvedOptions().locale,
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
timezone_offset: -(new Date().getTimezoneOffset() / 60),
}
});
# In liveview mount
if connected?(socket) do
Logger.info("SOCKET PARAMS: #{inspect get_connect_params(socket)}")
end
# And the result
[info] SOCKET PARAMS: %{
"_csrf_token" => "...",
"_mounts" => 0,
"_track_static" => ["..."],
"locale" => "fr",
"timezone" => "Europe/Zurich",
"timezone_offset" => 2
}
So You could use websocket, but it does not seems You need this, You just want to localize your login form. => new?locale=whatever and retrieve the locale server side.
Use an id to the new link, and add locale params to the path of this link with js.
KP123
It’s not magic it’s part of the browser spec. My point being that it’s not Phoenix specific.
Popular in Discussions
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
- #javascript
- #code-sync
- #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








