robinmonjo
Ajax call in phoenix (respond_to :js in rails)
Hello everyone,
I have been spending some times Googling but didn’t find anything. In rails there is a way to do ajax call like this:
link_to some_path, remote: true
Then we can accept the js format controller side and render a view.js.erb that executes some JS directly on the page.
I wonder if this is doable in Phoenix. Should I write raw javascript ? Or is there something similar than in rails ?
Regards,
Robin
Most Liked
yurko
I call the functions from the service layer (that use models) that return :ok or error tuples, same as you do in controllers.
To avoid having too much dom manipulation I render templates to strings (same partials that are used on render) and pass them to frontend, so channels work much like controllers.
On the front end you might get away with jQuery (I did in the latest app), since there’s not much JS this way. For a proper SPA I’d go for Vue or React or something.
It’s not easy to deliver an example without over-simplifying or polluting it with non relevant parts, I’ll do my best though, hope it still paints a picture ![]()
// some_socket.js
// import base socket stuff and create a socket / channel vars
const getItems = (opts, onSuccess, onError) => {
base.pushMessage(channel, "get-items", opts, onSuccess, onError);
};
export {someSocket as socket};
export {getItems as getItems};
// some_template_partial.html.eex
let someSocket = require('app/some_socket');
someSocket.socket.connect();
let onSuccess = function(response) {
$("#partial-id").replaceWith(response.some_html_string);
// render info notification
}
let onError = function(response) {
// render error notification
}
$someElement.click(function(e){
e.preventDefault();
// get relevant data from dom
someSocket.getItems(data, onSuccess, onError);
});
// some_channel.ex
def handle_in("get-items", payload, socket) do
case SomeService.get_items(payload) do
{:ok, items} ->
html = render_to_string(LayoutView, "partials/some.html", [socket: socket, items: items])
{:reply, {:ok, %{some_html_string: html}}, socket}
{:error, reason} -> {:reply, {:error, %{reason: reason}}, socket}
end
end
Also check out Drab and Unpoly as suggested by @OvermindDL1 - they use similar idea but provide more abstractions.
What I find nice about this approach - it’s pretty clean and organized (despite all the love jQuery front ends get), very fast (often feels like working offline) and you get less rituals with all the actions, api routes etc that you get when working with AJAX.
murtza
Rails uses jquery-ujs to perform ajax calls and you can use it in your phoenix project by making little changes. i.e you can copy jquery-ujs/src/rails.js at master · rails/jquery-ujs · GitHub into your app.js and change csrf-token to _csrf_token as following
// Up-to-date Cross-Site Request Forgery token
csrfToken: function() {
return $('meta[name=_csrf_token]').attr('content');
},
Now you can add "data-remote": "true" in form_for and your form will be submitted as xhr request. for example.
<%= form_for @changeset, @action, ["data-remote": "true"], fn f -> %>
You can add render(conn, "create.js.eex") in your controller just like rails.
i haven’t tested it yet but i hope it will work.
aseigo
Sort of in left field here, but depending on what you are trying to do … you may be able to use the UserSocket instead which in theory should be lighter weight / faster. The client would send it’s request over the websocket and it would respond with the appropriate data, which the client would then act on. Just a thought…
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









