tubedude
I’m working with LiveView.assign_async, which provides :ok, :failed, and :loading statuses. I think it would benefit from adding a :not_asked status.
The assign I’m working with, which I’ll just call state for now, only gets triggered after a user action. So at mount/3, the state is nil.
In render, I have to wrap any checks on state, like state.ok? or state.loading, with a nil check first. Here’s what I’ve tried:
Checking for state = nil
<div :if={@state[:ok?]}>Not asked, the state is nil</div>
This works fine, but when state switches to AsyncResult.loading, it throws an Access error:
(UndefinedFunctionError) function Phoenix.LiveView.AsyncResult.fetch/2 is undefined (Phoenix.LiveView.AsyncResult does not implement the Access behaviour)
Workaround 1: Wrapping Everything
One option is to wrap every state check inside a nil check:
<div :if={!is_nil(state)}>
<div :if={state.ok?}>Success on showing state</div>
<div :if={state.loading}>Hold on, loading...</div>
<div :if={state.failed}>There was an error!</div>
</div>
This works but starts to get cumbersome when state needs to be checked in multiple places across the page.
Workaround 2: Initialize with :not_asked
The other approach is to initialize state as AsyncResult.failed(%AsyncResult{}, :not_asked):
<div :if={state.ok?}>Success on showing state</div>
<div :if={state.loading}>Hold on, loading...</div>
But when handling failures, you need to differentiate between actual errors and the :not_asked state:
<div :if={state.failed}>There was an error. Wait! It might just be that it wasn’t asked yet.</div>
<div :if={state.failed != :not_asked}>There was a real error</div>
<div :if={state.failed == :not_asked}>Press here to load</div>
Suggested Improvement: Add :not_asked Status
I think it would be helpful to add a :not_asked status, so you can handle these cases more cleanly. One would need to initiate the assign, but after that, it would be easier to work with.
<div :if={state.ok?}>Success on showing state</div>
<div :if={state.loading}>Hold on, loading...</div>
<div :if={state.failed}>There was an error, a real one.</div>
<div :if={state.not_asked}>Press here to load</div>
Adding a :not_asked status simplifies the logic and removes the need for repetitive nil checks. It would make the state handling in LiveView.assign_async cleaner, especially in situations where user actions trigger the state change.
A PR could look like this:
Trending in Proposals: Ideas
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #blog-post
- #ai
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 2- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
tubedude
By the way, this is inspired by: How Elm Slays a UI Antipattern | Kris Jenkins' Blog
tubedude
The pull request to introduce this logic was denied, but we gained some good insights on how to get the same behaviour with the primitives that are available now.