type1fool

type1fool

Defoverridable Function Fallbacks for LiveView Callbacks

@ryanwinchester Thanks for this article! I knew this was possible, and the examples made it clear how to implement handler fallbacks. This is super useful in the MyAppWeb.live_view/0 macro, where I don’t want to crash on unhandled events and messages.

Why Do This?

When a form control uses phx-debounce, often, an event will be triggered even after the user has submitted the form. For example, if a form has both phx-change & phx-submit events and an input uses phx-debounce="blur" or some large debounce timeout (200+), a user will often quickly type a value and hit Enter. When this happens, the submit event is triggered, the user may be redirected to another route, and the change event will be routed to a LiveView which wasn’t expecting it.

I applied the approach in the article to the MyAppWeb.live_view/0 macro, and now, those debounced events show up as logger warnings instead of crashing the socket. The user experience is much better this way, and now I can remove several copies of fallback event/message handlers that are no longer necessary.

Nice work!

Default LiveView Behavior?

Now, I wonder if this should be the default behavior in new LiveView applications. I vaguely remember @chrismccord mentioning real-world lessons learned after working at Fly, particularly how “let it crash” isn’t ideal for some (most?) user interfaces. The context was more around async tasks, but I think there’s a case to be made for gracefully handling unexpected events, messages, and providing some fallback implementations for the LiveView behaviour. Logging warnings seems like a good balance that will prevent Sentry and other error alerts when this common user behavior trips up our LiveView apps.

Most Liked

chrismccord

chrismccord

Creator of Phoenix

Latent debounces shouldn’t be happening if the form has been submitted as we specifically have code to handle this. Can you put together a minimal issues that reproduces the problem? Thanks!

Last Post!

type1fool

type1fool

On a fresh app with Phoenix 1.7.14 and PhoenixLiveView 1.0.0-rc.6, I can confirm debounced change event appears to be processed before the form submission event.

https://github.com/type1fool/yolo/tree/main/lib/yolo_web/live

[debug] HANDLE EVENT "validate" in YoloWeb.DebounceLive
  Parameters: %{"_target" => ["yolo", "name"], "yolo" => %{"name" => "as0d9f8as09df80a9sdf09as8df9asd08f"}}
[info] [validate: %{"name" => "as0d9f8as09df80a9sdf09as8df9asd08f"}]
[debug] Replied in 872µs
[debug] HANDLE EVENT "pewpew" in YoloWeb.DebounceLive
  Parameters: %{"yolo" => %{"name" => "as0d9f8as09df80a9sdf09as8df9asd08f"}}
[info] [pewpew: %{"name" => "as0d9f8as09df80a9sdf09as8df9asd08f"}]
[debug] Replied in 454µs
[debug] MOUNT YoloWeb.PewpewLive
  Parameters: %{"name" => "as0d9f8as09df80a9sdf09as8df9asd08f"}
  Session: %{"_csrf_token" => "bEgWWu1cumbHhHVjCdmIbyn0"}
[debug] Replied in 121µs

There still seems to be value in preventing socket crashes when unexpected events and messages are received by a LiveView.

  • During development, warning/error logs could raise awareness for developers about what’s happening in a way that might be clearer than the socket crash error.
  • In production, users would be less alarmed when an omission or mistake has happened in the code, and developers could customize and opt into error logs.

I’m thinking of cases where a complex application uses PubSub, where a new message arrives in a topic and one or more subscribing LVs hasn’t been updated to handle it. Ideally, this would never happen, but mistakes and oversights do creep in sometimes.

The beauty of the fallback implementations is that the framework could still log errors by default without showing the big red flash to users. I understand it’s debatable whether crashes are good or bad UI and whether unexpected events & messages should be conveyed to the user at all. Outside of Phoenix, it seems that kind of thing would be logged to the browser console, and not always presented in the UI.

TLDR: Should it crash?

Where Next?

Popular in Discussions Top

PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
scouten
I’m looking for a host for the server part of a small (personal) side project that I’m working on. It’s currently written in Node.js and ...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54996 245
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
mikl
I wanted to capitalize a string, and tried using String.capitalize(). That generally works well, until you try to capitalize a word like...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
arcanemachine
https://nitter.net/josevalim/status/1744395345872683471 https://twitter.com/josevalim/status/1744395345872683471
New

Other popular topics Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 42576 114
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement