DEV Community

Cover image for How to take leverage from on_mount to reduce code
Herminio Torres
Herminio Torres

Posted on

How to take leverage from on_mount to reduce code

Phoenix LiveView has implemented some fantastic features, and one of them is the on_mount/1 callback function.

This callback function will run before the mount/3 function in your LiveView.

There are two ways to set the on_mount callback function:

  1. In router using live_session/3.
  2. In your LiveView modules with on_mount macro.

If you need to do something before the mount/3 in all your LiveViews, live_session/3 is likely the best fit. However, if only for a few of them, the on_mount macro will be better for your needs.

on_mount helps reduce repetitive code in your LiveViews. Let's look at an example.

defmodule ExampleWeb.UserHook do
  import Phoenix.LiveView

  def on_mount(:default, _params, %{"current_user" => current_user} = _session, socket) do
    if authorized?(current_user) do
      {:cont, socket}
    else
      {:halt, socket}
    end
  end

  def on_mount(:admin, _params, %{"current_user" => current_user} = _session, socket) do
    if admin?(current_user) do
      {:cont, socket}
    else
      {:halt, socket}
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

The live_session/3 on Router:

live_session :default, on_mount: ExampleWeb.UserHook do
  scope "/", ExampleWeb do
    pipe_through [:browser, :auth]

    live "/", HomeLive, :page
  end
end
Enter fullscreen mode Exit fullscreen mode

The on_mount macro:

defmodule ExampleWeb.HomeLive do
  use ExampleWeb, :live_view

  on_mount {ExampleWeb.UserHook, :admin}

  def mount(_params, _session, socket) do
    # ...
  end
end
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
azyzz profile image
aziz abdullaev

You can also pass on_mount directly in the routes/live_session:

    live_session :vendor_dashboard, on_mount: [{MyAppWeb.VendorAuth, :ensure_not_suspended}] do
      live "/new", Vendor.NewOrdersLive
    end
Enter fullscreen mode Exit fullscreen mode

where:


  def on_mount(:ensure_not_suspended, _params, session, socket) do
    socket =
        Phoenix.Component.assign_new(socket, :current_vendor, fn ->
      if vendor_token = session["vendor_token"] do
        Accounts.get_vendor_by_session_token(vendor_token)
      end
    end)

    case socket.assigns.current_vendor.status do
      "SUSPENDED" ->
        {:halt,
         Phoenix.LiveView.redirect(socket,
           to:
             "/error"
         )}
      _ ->
        {:cont, socket}
    end
  end
Enter fullscreen mode Exit fullscreen mode
Collapse
 
herminiotorres profile image
Herminio Torres

Thank you, @azyzz, for pointing it out; I put it this way since in one of my previous blog posts, I put more on that direction to use live_session, and I keep it this way to show some other alternatives to use the on_mount.