paulofabiano
State Machine: current state's path
Hey, guys!
I implemented a state machine with Machinery to control the UI sequence I show to my user. But I have a problem.
When I am in the :ready state, I show a live_component A with Card. This card contains a question and possible answers. If the user selects the answer 1, I change the state to, let’s say “A1” and I show the next live_component B. If the user selects answer 2, I change to “A2” and show the next component C.
So far so good. This is a very basic transition and everything is working well. In my LiveView each live_component is wrapper within a condition like:
if state == “ready” do live_component A end
if state == “A1” do live_component B end
if state == “A2” do live_component C end
What’s the problem? Each live_component is shown one below the other.
So, when I transit to state “A1”, the live_component A is hidden.
So, I needed some way to construct a breadcrumb of the current state, from the initial one until the current state, like: path => [“ready”, “A1”, “B2”, “C1”]
This way, I could have:
if Enum.member?(path, “ready”) do live_component A end ← visible
if Enum.member?(path, “A1”) do live_component B end ← visible
if Enum.member?(path, “A2”) do live_component C end
if Enum.member?(path, “B1”) do live_component D end
if Enum.member?(path, “B2”) do live_component E end ← visible
if Enum.member?(path, “C1”) do live_component F end ← visible
if Enum.member?(path, “C2”) do live_component F end
I thought about using Machinery’s log_transition to manage by my own this new path property. Basically, it would be keeping and appending a new state at the end of the path list.
So, I’d like your opinion about this approach. Not sure if it is the nicest one. I’ve been researching also about the Zipper list/tree and some implementations seem to keep this path as we navigate the tree.
First Post!
APB9785
Maybe instead of having just one state, use multiple assigns like:
def mount(_params, _session, socket) do
socket = assign(socket, choice_A: nil, choice_B: nil, choice_C: nil)
{:ok, socket}
end
Then when a choice is made,
assign(socket, choice_A: 1)
# or
assign(socket, choice_A: 2)
and in the html.leex
<%= live_component @socket, LiveComponentA %>
<%= if @choice_A == 1 do %>
<%= live_component @socket, LiveComponentB %>
<% end%>
<%= if @choice_A == 2 do %>
<%= live_component @socket, LiveComponentC %>
<% end%>
<%= if @choice_B == 1 do %>
<%= live_component @socket, LiveComponentD %>
<% end %>
<%= if @choice_B == 2 do %>
<%= live_component @socket, LiveComponentE %>
<% end %>
etc…
Last Post!
paulofabiano
Hey ![]()
Yes, that works but … I don’t know.
I created an issue anyways in the Machinery repo to discuss this: Does it worth thinking about tracking transitioned states? · Issue #77 · joaomdmoura/machinery · GitHub
Having a new field called path and accessible like state would be interesting. Please, join the thread in there as well ![]()
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security









