Logo

dev-resources.site

for different kinds of informations.

Connectivity status with Phoenix LiveView

Published at
5/27/2024
Categories
elixir
liveview
phoenix
Author
ndrean
Categories
3 categories in total
elixir
open
liveview
open
phoenix
open
Author
6 person written this
ndrean
open
Connectivity status with Phoenix LiveView

Some notes on how to display - outside of a LiveView - the status of the connection by rendering images using the callback onBeforeElUpdated.

We define an <img> tag somewhere in "root.html.heex" or "app.html.heex" and want to set its src attribute depending upon the connection status, "online" or "offline".

<img width="30px" alt="line-status" id="online-status" />
Enter fullscreen mode Exit fullscreen mode

The connection status is accessible in the browser with the navigator.onLine boolean.

The connection change is captured by the window interface events online and offline.

We define the callbacks to these events: we append a given image file to the src attribute with some styling.

// /assets/js/onlineStatus.js

const domEl = document.getElementById("online-status");

const status = {
  online: { src: "/images/online.svg", bg: "lavender", opacity: 0.8 },
  offline: { src: "/images/offline.svg", bg: "tomato" },
};

const setOnline = (el, { opacity = 1, bg, src }) => {
  el.style.opacity = opacity;
  el.src = src;
  el.style.backgroundColor = bg;
};

export function statusListener() {
  const domEl = document.getElementById("online-status");

  setOnline(domEl, navigator.onLine ? lineStatus.on : lineStatus.off);

  window.addEventListener("offline", () => 
    setOnline(domEl, lineStatus.off))

  window.addEventListener("online", () => 
    setOnline(domEl, lineStatus.on))
}


export { statusListener };
Enter fullscreen mode Exit fullscreen mode

We import and use this function in our Javascript "app.js" file:

// /assets/js/app.js

import {statusListener} from "./onlineStatus.js"

statusListener()
Enter fullscreen mode Exit fullscreen mode

It remains to solve the first render problem. Indeed, unless we set a initial src attribute on the <img> element above, which we don't want, the LiveView DOM patching won't rendering anything. The snippet below doesn't work:

navigator.onLine ? setOnline(domEl, status.online) : setOnline(domEl, status.offline)
Enter fullscreen mode Exit fullscreen mode

This can be solved with the onBeforeElUpdated callback. It lets you perform your own DOM patching, independently from LiveView, on whatever DOM element you name from into a transformed DOM element named to.
This callback is attached to the dom property of the LiveSocket under the key onBeforeElUpdated. It looks like this:

We add a say firstRender function in our custom JS file and add our snippet:

// /assets/js/onlineStatus.js

const firstRender = (from, to) => {
  if (from.getAttribute("id") === "online-status") {
    navigator.onLine
      ? setOnline(to, status.online)
      : setOnline(to, status.offline);
  }
}

export {firstRender, statusListener }
Enter fullscreen mode Exit fullscreen mode

and then append it to our LiveSocket in the "app.js":

// /assets/js/app.js
import {statusListener, firstRender} from "./onlineStatus.js"

const liveview = new LiveSocket("/live", Socket, {
  longPollFallbackMs: 2500,
  params: { _csrf_token: csrfToken },
  dom: { onBeforeElUpdated: firstRender },
  },
});

liveview.connect();
statusListener();
[...]
Enter fullscreen mode Exit fullscreen mode

Examples of SVGs

The "/priv/static/images/online.svg" file example:


<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path xmlns="http://www.w3.org/2000/svg" d="M 5.78125 4.1875 C 3.48125 6.0215 2 8.837 2 12 C 2 15.163 3.48125 17.9785 5.78125 19.8125 L 7.03125 18.25 C 5.19125 16.783 4 14.53 4 12 C 4 9.47 5.19125 7.217 7.03125 5.75 L 5.78125 4.1875 z M 18.25 4.1875 L 17 5.75 C 18.83 7.218 20 9.477 20 12 C 20 14.523 18.83 16.782 17 18.25 L 18.25 19.8125 C 20.538 17.9775 22 15.154 22 12 C 22 8.846 20.538 6.0215 18.25 4.1875 z M 8.28125 7.3125 C 6.90125 8.4125 6 10.102 6 12 C 6 13.898 6.90125 15.5875 8.28125 16.6875 L 9.53125 15.125 C 8.61225 14.391 8 13.265 8 12 C 8 10.735 8.61225 9.609 9.53125 8.875 L 8.28125 7.3125 z M 15.75 7.3125 L 14.5 8.90625 C 15.416 9.64025 16 10.739 16 12 C 16 13.262 15.415 14.36075 14.5 15.09375 L 15.75 16.6875 C 17.122 15.5875 18 13.892 18 12 C 18 10.108 17.123 8.4135 15.75 7.3125 z M 12 10.5 C 11.171573 10.5 10.5 11.171573 10.5 12 C 10.5 12.828427 11.171573 13.5 12 13.5 C 12.828427 13.5 13.5 12.828427 13.5 12 C 13.5 11.171573 12.828427 10.5 12 10.5 z"/>
</svg>
Enter fullscreen mode Exit fullscreen mode

The "/priv/static/images/offline.svg" example:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path xmlns="http://www.w3.org/2000/svg" d="M 3.90625 2.28125 L 2.5 3.71875 L 4.34375 5.5625 C 2.8847559 7.2990879 2 9.55875 2 12 C 2 15.162 3.48125 17.9785 5.78125 19.8125 L 7.03125 18.25 C 5.19125 16.783 4 14.53 4 12 C 4 10.111392 4.6813379 8.3690147 5.78125 7 L 7.1875 8.40625 C 6.44465 9.4038808 6 10.663008 6 12 C 6 13.898 6.90125 15.5875 8.28125 16.6875 L 9.53125 15.09375 C 8.61225 14.35975 8 13.265 8 12 C 8 11.214008 8.2597973 10.490055 8.65625 9.875 L 10.53125 11.75 C 10.517412 11.831789 10.5 11.91425 10.5 12 C 10.5 12.828 11.172 13.5 12 13.5 C 12.08575 13.5 12.168169 13.482588 12.25 13.46875 L 20.5 21.71875 L 21.90625 20.28125 L 3.90625 2.28125 z M 18.25 4.1875 L 17 5.75 C 18.83 7.217 20 9.477 20 12 C 20 13.194 19.722 14.2945 19.25 15.3125 L 20.71875 16.8125 C 21.51475 15.3805 22 13.751 22 12 C 22 8.846 20.538 6.0215 18.25 4.1875 z M 15.75 7.3125 L 14.5 8.875 C 15.416 9.609 16 10.738 16 12 C 16 12.027 16.001 12.0355 16 12.0625 L 17.71875 13.78125 C 17.89975 13.21225 18 12.628 18 12 C 18 10.108 17.123 8.4135 15.75 7.3125 z"/>
</svg>
Enter fullscreen mode Exit fullscreen mode
liveview Article's
30 articles in total
Favicon
Phoenix LiveView, hooks and push_event: json_view
Favicon
Phoenix LiveView is slot empty?
Favicon
Bridging the Gap: Simplifying Live Component Invocation in Phoenix LiveView
Favicon
Optimize LiveView Performance with Temporary Assigns
Favicon
Phoenix LiveView Optimization Guide
Favicon
Better LiveView Hooks with Typescript
Favicon
Automatically clearing flash messages in Phoenix LiveView
Favicon
Debug and visualise TailwindCSS document structure
Favicon
Build a small chat service using Elixir and deploy it on Amazon ec2 using AWS (Part 1)
Favicon
Build a small chat service using Elixir and deploy it on Amazon ec2 using AWS (Part 2)
Favicon
Weather API: A GenServer and LiveView Implementation Part I
Favicon
Build a small chat service using Elixir and deploy it on Amazon ec2 using AWS (Last part)
Favicon
Backpex - a highly customizable admin panel for Phoenix LiveView applications
Favicon
AI powered app (with open-source LLMs like Llama) with Elixir, Phoenix, LiveView, and TogetherAI
Favicon
Using Ecto (without Db) for validating Phoenix form
Favicon
Adding stream_async() to Phoenix LiveView
Favicon
SaladUI - Implement avatar component for Phoenix LiveView
Favicon
Connectivity status with Phoenix LiveView
Favicon
Phoenix Liveview components for Shadcn UI
Favicon
Ash - Create with relationship
Favicon
My Failed Student Housing App
Favicon
Beter data-confirm modals in Phoenix LiveView
Favicon
Free Beginner Friendly LiveView Course in English and Portuguese
Favicon
LiveView + WebComponents = 🚀
Favicon
Ash AshSqlite - Aggregates not supported
Favicon
Phoenix Liveview - open editor for element
Favicon
Ash Calculations - Cond
Favicon
How does Ecto.Schema's `has_one/3` works?
Favicon
Creating a Date Range Picker with Phoenix LiveView
Favicon
Listing matches for users

Featured ones: