Phoenix Framework: send rendered template in JSON response

I have a template for the top navigation of my application in top_navigation.html , which contains "Log in", "Register" and when logging in to the "Logout" system.

 <%= if logged_in?(@conn) do %> <li><%= link "Sign out", to: session_path(@conn, :delete), method: :delete %></li> <% else %> <li><a href="#" class="js-register" data-toggle="modal" data-target=".js-register-modal">Sign up</a></li> <li><a href="#" class="js-login" data-toggle="modal" data-target=".js-login-modal" >Sign in</a></li> <% end %> 

I register the user through AJAX, but after they logged in, I would like to change the top navigation using the newly created template (showing the "Exit" link), passed back to the client in the login.

Is there a way to send a processed template as part of a JSON response?

Something along the lines of:

 defmodule MyApp.SessionController do use MyApp.Web, :controller def create(conn, %{"user" => user_params}) do case MyApp.Session.login(user_params, MyApp.Repo) do {:ok, user} -> conn |> put_session(:current_user, user.id) |> json %{ top_navigation: render("top_navigation.html") } # ^^^^ this doesn't work ^^^^ :error -> conn |> put_status(404) |> json %{ message: "Unable to sign in." } end end def delete(conn, _) do conn |> delete_session(:current_user) |> put_flash(:info, "Signed out.") |> redirect(to: "/") end end 

And Javascript:

 $(".js-login").on("click", e => { e.preventDefault() $(".js-login-alert").hide() }) $("#login").on("submit", e => { e.preventDefault() let form = $("#login") let data = { _csrf_token: $( 'input[name="_csrf_token"]' ).val(), user: { email: form.find('input[name="email"]' ).val(), password: form.find('input[name="password"]').val() } } $.ajax({ type: "POST", url: "/login", data: data, success: e => { $(".js-top-navigation").html(e.responseJSON["top_navigation"]) // ^^^^^^^^^^^^^^ This is where we swap it out ^^^^^^^^^^^^^^^ $(".js-login-modal").modal("toggle") }, error: e => { let alert = $(".js-login-alert") alert.text(e.responseJSON["message"]) alert.show() } }) }) 

Thank you very much in advance!

+5
source share
1 answer

Yes indeed! Phoenix templates are simply functions on their view module. Thus, you can display the template by calling the function:

 |> json(%{nav: Phoenix.View.render_to_string(MyView, "nav.html", conn: conn)}) 
+4
source

Source: https://habr.com/ru/post/1233451/


All Articles