The worst way to handle sessions using Phoenix LiveView.
Tags: liveview, phoenix, elixir, beginners
Published: 2022-07-12 17:23:27

# Greeting

Hello #devElixir!!! Welcome to #FullStackElxpro

Here we discuss strategies and tips for your Elixir learning journey. This is from scratch until your first wave as an elixir developer

I am Gustavo and today's theme is: **The worst way to handle sessions using Phoenix LiveView.**

_ps: You can follow the article with **[VIDEO](https://youtu.be/0_XNM-JvcT8)**

**Do you want to learn Elixir in three months? https://elxpro.com/sell**

_Want to learn more about elixir on a Telegram channel?_
https://elxpro.com/subscribe-elxcrew


# Which is?

The session is something temporary in an application. It is nothing more and nothing less than that.

However, in Elixir, Phoenix, and Liveview (mainly the web part) there are several ways to work with the session.

Can use:

## [Plugs](https://hexdocs.pm/phoenix/plug.html)


Which is a connection middleware and through this middleware persists data and reads data in a session. And there are several plugs to deal with this middle of this one, but this is not the case in this article


## [Phoenix Token](https://hexdocs.pm/phoenix/Phoenix.Token.html)

And a way to use and save data that expires in a simple way


## Live view

There are several ways like session_storage, local_storage (as long as you use hooks), and live_session. And you can check out all kinds of approaches.

What is your live_session and why use it, as several advantages and approaches are straightforward that will in this article make a difference in the maintenance and readability of the application.


# What is the difference between **sessions** and **live_session**?

The main difference is that the main focus of the session is on the connection, the persistent data traffic on the connection.

Now in the live_session you can get the data from the _session_, include it in the **socket**, and also program generic events on your page, which is a lot not to replicate code, in short, it's a middleware with superpowers.




# How did you find this out?

The way I found out, was by reading the phoenix 1.5 to 1.6 update. And when the **_session** appeared, I thought there was no need for live. But I had pagination in an app that was working on a shared header using a live view within a live view.

If you understand processes, there was one process monitoring another an absurd complexity to create communication, it took a long time to understand how **OTP, Elixir, Processes under the hood and I even understand it all, and one solution (solution) was so verbose and complicated to handle.

At this event I had already worked with **live_session** on other projects (outside the Company), and I saw the power and amount of benefits that live_session brings to the new version of **Phoenix Liveview** through a conversation about code decisions I presented the solution and everyone liked it and the implementation was very simple.

_ps: (I won't show a solution developed in this article, however, in the end, you will be able to create solutions better than I implemented)_


# Why is **live_session** important?

The great importance and question of superpowers that are easy to use. One of the game changers from version 1.5 to 1.6 was _live_session_ because you don't need to write a lot of code, with just a few lines you'll be able to interact with the socket and include implementations and events, and especially create user rules.

# What is the biggest benefit of **live_session**?

The biggest benefit is the issue of handling a socket as a session.


# Do you remember any stories where this was important to you?

As I mentioned, the main one was your question about information generically designated in the socket, without having to replicate code something that the developers think and are.

And the other one was when I needed to trigger events from **handle_events, handle_infos, handle_params** without having to implement it on every page



# How to create **live_sessions**?


You can start by understanding why. Some questions may help you:


- Do I need to share this information on more than 1 page?
- Does this event need to be replicated on more than one page?
- Do I need to create any generalized trading rules?


If the answer is yes, **[live_session](https://hexdocs.pm/phoenix_live_view/Phoenix.LiveView.Router.html#live_session/3)** is the best option.

You can see in the image below that it was necessary to implement just a few lines of code and live_session starts to behave like a _middleware_


![Image Description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dw10zivsq0roly4fvjvj.png)

Before starting any session what **live_session** will do is call the permission module, check the scope (which is more than amazing pattern matching), and sign new information into the socket.


 

```
defmodule LiveSessions.Permissions do
  import Phoenix.LiveView
  alias FoodOrder.Accounts
  alias FoodOrderWeb.Router.Helpers, such as: Routes
  alias LiveSessions.CreateCart

  def on_mount(:user, _params, %{"user_token" => user_token}, socket) do
    assign_user(socket, :user, user_token)
  The end

  def on_mount(:admin, _params, %{"user_token" => user_token}, socket) do
    assign_user(socket, :admin, user_token)
  The end

  defp assign_user(socket, _,nil) do
    error_login(socket, "You must be logged in")
  The end

  defp assign_user(socket, :user, user_token) do
    current_user = Accounts.get_user_by_session_token(user_token)
    cart_id = get_connect_params(socket)["cart_id"]

    socket =
      socket
      |> assign_new(:current_user, fn -> current_user end)
      |> CreateCart.execute(cart_id)

    {:cont, socket}
  The end

  defp assign_user(socket, :admin, user_token) do
    user_token
    |> Accounts.get_user_by_session_token()
    |> return_socket(socket)
  The end

  defp return_socket(%{role: role}, socket) when role != :ADMIN,
    do: error_login(socket, "You do not have permission to access this page")

  defp return_socket(current_user, socket),
    do: {:cont, assign_new(socket, :current_user, fn -> current_user end)}

  defp error_login(socket, message) do
    socket =
      socket
      |> put_flash(:error, message)
      |> redirect(to: Routes.main_path(socket, :index))

    {:stop, socket}
  The end
The end
```


# Wrap up


I hope I helped you in your learning, I always recommend visiting youtube videos, it usually has more resources. A big hug!!



Social networks:

- Gustavo Oliveira - https://www.linkedin.com/in/gustavo-oliveira-642b23aa/
- Elxpro Linkedin - https://www.linkedin.com/company/36977430)
- Twitter - https://twitter.com/elx_pro
- ElxproBr - https://www.youtube.com/channel/UCl_BBK2sXZzQy_3ziNU7-XA)
- Elxpro - https://www.youtube.com/channel/UCLzHBFuE6oxPdP6t9iqpGpQ)