All Episodes

December 9, 2024 53 mins
Join us on today's episode as we interview David Khourshid. We will learn about state machines, how XState plays nice with Angular right out of the box and how we can use XState Store to build light weight state machines for simple state.

More about David 

BlueSky: @davidkpiano.bsky.social
X:@DavidKPiano
LinkedIn: David Khourshid 

Follow us!
X: The Angular Plus Show
BlueSky: @theangularplusshow.bsky.social

The Angular Plus Show is a part of ng-conf. ng-conf is a multi-day Angular conference focused on delivering the highest quality training in the Angular JavaScript framework. Developers from across the globe converge on Salt Lake City, UT every year to attend talks and workshops by the Angular team and community experts.
Join: http://www.ng-conf.org/
Attend: https://ti.to/ng-conf
Follow: https://twitter.com/ngconf
             https://www.linkedin.com/company/ng-conf
             https://bsky.app/profile/ng-conf.bsky.social
             https://www.facebook.com/ngconfofficial
Read: https://medium.com/ngconf 
Watch: https://www.youtube.com/@ngconfonline

Edited by Patrick Hayes https://www.spoonfulofmedia.com/ 
Stock media provided by JUQBOXMUSIC/ Pond5
Mark as Played
Transcript

Episode Transcript

Available transcripts are automatically generated. Complete accuracy is not guaranteed.
Speaker 1 (00:08):
Welcome to the Angular plus Show. We're app developers of
all kinds share their insights and experiences. Let's get started.

Speaker 2 (00:21):
Hello, and welcome back to another episode of the Angular
Plus Show. My name is Lara Newsome. I will be
one of your hosts today and with me is Chow
Tran Chow. How are you today?

Speaker 3 (00:32):
Good?

Speaker 4 (00:33):
How are you?

Speaker 3 (00:33):
I'm very excited for this episode.

Speaker 2 (00:34):
By the way, I am too because, as I realized,
I don't really know very much about state machines. So
to kick that off, our guest today is David Khorshe. David,
Welcome to the Angular Plus Show.

Speaker 4 (00:49):
Hello, thanks for having me.

Speaker 2 (00:50):
Absolutely So besides X state and State machines, do you
want to tell us a little bit about yourself?

Speaker 4 (00:58):
Sure? So my name is David Sheet, not David Piano.
I just used David KPN and pretty much everywhere in
line and that's where you could find me. So I yeah,
I've been a developer for use over fifteen years or so.
I actually went to school for piano performance, so that's
why I do piano and also development, and yeah, State

(01:19):
machines have just been interesting to me for many, many
many years.

Speaker 2 (01:23):
Interesting. So okay, I have a master of fine arts
in art and integrated media. So I'm glad to welcome
another random degree holding onto the show. What I just
real quick, what took you from piano performance to software engineering?

Speaker 4 (01:45):
Well, so I was always interested in building websites, managed
PHPBV forums back in the day, you know, basic gatestml J, Query,
things like that, and I realized that as a as
a pianist, you you can make a little a little
bit more money doing software developments than piano. So that's
where I ended up. And I actually started in college

(02:08):
just working on WordPress websites and then actually getting into
CSS a lot more than javascripts. So I was obsessed
with that for a while, but then eventually became a
full rounded web developer.

Speaker 2 (02:20):
Nice. Yeah, I think a lot of us have that
same story of like realizing that our chosen career is
not very profitable and also realizing that the way that
my brain worked for art is very helpful for software engineering,
and so it was just sort of a natural fit
and then it kind of takes off from there. So well,

(02:43):
I'm glad you made the switch. And so, okay, my
first question, because I realized I don't know what a
state machine is, can you explain what a state machine is.

Speaker 4 (02:53):
Sure, so, state machines are one of those things that
it sounds like a very confusing topic, like a theoretic
you need a computer science degree to understand it. But honestly,
like one of my biggest missions over the last five
or more years has been to make it intuitive for people,
even if you're not a developer, because honestly, state machines

(03:14):
are conceptually simple. So just to start off with an example,
as a human, we're either asleep or awake, and so
we could describe those two things as different states. And
we can't be both asleep and awake at the same time.
I mean, if you are, please contact your doctor medical advice.

(03:35):
But we transition, and so that's a key word. We
transition from one states to another. So transitions happen based
on events. So for example, if we're asleep and an
alarm goes off, and we could transition to the awake states.
And if we're awake and you know, we are overcome
with exhaustion, lay in bed then or you know, maybe

(03:56):
after a turkey dinner on Thanksgiving we just go to
bed and then we yeah, yeah, we fall asleep. So
state machines describe those transitions between states. So they describe
the main parts are the different states in which you
can only be in one state at a time, Like
I described the transitions between the states and the events

(04:19):
that cause those transitions, and really that's all there is
to it. So yeah, there's just many things like I'm
sure you learned the water cycle in school or basically
how water goes from ice to solid to gas and
how it could like transition between those states and what
causes those transitions. So in software development, state machines are

(04:39):
actually extremely useful because in many situations our applications can
really be described as these different states. A button can
be disabled until the form is valid, and then that
event causes the button to become enabled again. We could
have a form where you press submit and now the
form is submitting, and ideally nothing should happen when the

(05:01):
form is submitting, so the user shouldn't be able to
edit any information or submit the form again, and then
the form can transition to either being submitted or being
in an error state. So just being able to outline
these in sort of a low chart looking way is
extremely useful for not only software developers, but also the

(05:23):
entire team, so that even if they don't know how
to code, they can understand the logic behind, you know,
the different parts of their application. And so that's why
I think state machines are very useful and honestly also
very intuitive, because they become sort of this this language,
this ubiquitous language that developers and non developers alike can

(05:45):
use and understand. So, I know, state machine is a
scary term, but just think of it as a flow
chart that describes transitions between states.

Speaker 2 (05:53):
And so I was talking to child before the episode,
and I was realizing that I was combined. I was
confusing rules engines with state machines, and it sounds to
me like state machines are kind of, at least loosely
related to like a rules engine, where it's basically telling
you what what is possible and maybe that rules you know.

(06:16):
I think rules engines get pretty complicated and all of that,
but I state can as well, right so yeah.

Speaker 4 (06:25):
Right, yeah, yeah, yeah, they both have you know, similarities,
like for example, a rules engine, you know, you have
inputs and then based on the set of rules the
you know, decisions can be made, actions can be triggered.
And both state machines and rules engines work in a
deterministic way. So that's the other key points too, where
if you're in one state, the state machine defines or

(06:47):
it specifies that when this event happens in this date,
you will definitely go to this date, you will definitely
have these actions executed. It's not just some random oh
maybe this can happen, maybe that can happen. It's a
very exact behavior. Same thing with rules engines. You have
a set of rules that are deterministically applied and something

(07:08):
happens based on those rules.

Speaker 2 (07:11):
It sounds like it would be really easy, or I
say easy. I'm using easy in air quotes because I
think easy is relative to who you are and all
of that. But it sounds like state machines created a
path for also writing like integration tests or end tests,
because you can take the rules and the state that's

(07:33):
defined in those two determine what sort of test suites
you might need to write to validate that your application
is performing the state machine correctly. It's I don't know
performing is the right word.

Speaker 4 (07:45):
But yeah, executing your Yeah, that computer term, right, that's
actually a really good application because honestly, as developers, we
will right end to end test just covering basic use
cases or happy paths and then hoping that's enough, and

(08:05):
then eventually, inevitably we will encounter rebug and then we'll
realize why why did this bug happened? It's because we
didn't have a test that covers it, and so we
will write yet another test covering thats And the thing
is where we're just blindly or blindly, but we're like
randomly adding tests and test paths until you know, we

(08:27):
feel satisfactory with the amount of coverage, not realizing that
each one of these end to end test paths. You
could think of as Google maps. That's the analogy that
I'd like to make, where it's basically a path from
points A to point B, and there's first of all,
there's many possible ways to you know, go from point

(08:47):
A to point B, just like in in map software,
there's many possible ways that you could go. You could
go via the highway, via local roads. There might be
a detour, so you might go a different way. And
essentially the goal or the ideal goal with end to
end tests is that you cover all of those possible weights.
Of course that might be infeasible, but you know, what

(09:09):
when you cover those ways. Basically, each one of those
paths is describing part of the state machine. So if
you think of a state machine as this big flow
chart like graph, every end to end test is describing
one possible path through that state machine. And so if
you have a state machine that describes all of the
possible behavior and states and transitions in your app, then

(09:30):
it becomes possible to see what's missing, like what the
inside tests. But also you could get pretty clever and
you could say, well if I test this one path
that also covers all these other paths, Like the number
of times that I see people test like, oh, let's
make sure they could log in, let's make sure that
they could log out, and then they test like these

(09:51):
bigger paths where you have to log in anyway, It's like,
why are you doing so much work? Why is SEEI
taking four hours to run? You could just do one
path that cover everything? Yeah?

Speaker 2 (10:02):
Yeah, I feel like that's a easy, easy gotcha to
run into with and testing where you're not thinking holistically,
you're kind of thinking incrementally and nice and so with
a state machine, do they okay? So I also have
a botany degree. That's the other thing I have and
in botany, and they talk about taxonomy where it's dichotomous trees, right,

(10:23):
like is it this yes?

Speaker 4 (10:25):
Is it this no?

Speaker 2 (10:27):
Do state machines work sort of binary or is it
possible to be? Like which of these five states are
you in?

Speaker 4 (10:34):
A state can have mull or so, so what do
you mean by binary? Like the number of trains like
a yes or no decisions.

Speaker 2 (10:40):
Basically yes or no, like is this thing true or false?
About what just happened?

Speaker 4 (10:45):
Right, So, decision trees and state machines are a little
bit different, but you could think of each of these
choices as different events in the state machine. They're they're analogous,
and you could use state machines in that way too.
But in each state you can have zero or more
transitions from that state to different states. And there's also
things called guarded transitions, so you could say if an

(11:06):
events happened or so, when this event happens, if this
go here else, if this go there, else go there,
et cetera. So yeah, they're pretty similar in that way,
but it's not necessarily binary, just like decision trees aren't
necessarily binary either. You could have many possible decision points
going to different different nodes in that tree. Yeah.

Speaker 2 (11:29):
Absolutely, I'm like, yeah, ask me you a million questions.

Speaker 3 (11:33):
On like no, no, I just want to make a
remark on the end to end testing and using state
machines in the first place. Blah blah blah. We recently
just got like a bug in production and one of
the testas just just just put a common say, we
got in impossible state. And it is very relevant to

(11:57):
like a state machine, because with a state machine, is
probably not possible to get into like an impossible state.

Speaker 4 (12:05):
Yeah, that's exactly right. And I do mention like this
whole idea of impossible states a lot with state machines.
So just just to define the term, an impossible state is,
of course a state that should be keyword being should
be impossible to get to, like from one state to another.
So I'm trying to think of an example. I mean,

(12:28):
there's examples that happen in software all of the time
where it's like, Okay, if we're submitting a form and
the form is successfully submitted, then it makes absolutely no
sense for there to be a possible transition from submitted
to error. But I'm sure that you know you've probably
seen that a lot or another one. If a form

(12:49):
is submitting, then it shouldn't submit multiple times, so you shouldn't,
you know, keep going to that state and redoing that submission.
And so with state machines, staate machines are a map
medical model. And I know I'm making it sound a
lot more complex than it is, but it's essentially just
a transition function. And the transition function states, when you're

(13:10):
in this state and this event happens, you will always
go to this date and maybe you know, perform these effects,
so you will not go to some other states. And
so what that means is that it becomes impossible if
there is no transition defined for some events in some states,
it becomes impossible for you know, any transition to be taken.

(13:31):
So I love usings dimitting a form as a classic
example of this, because there have been so many times
where I'm like, hey, I wonder what happens by presss
submit button ten times and guess what ten submissions happen?
You know, things go wrong. People DM me saying was
this you like, there's twenty different you know submissions of
this form again exactly exactly. But if you have a

(13:56):
state machine or something similar, to a state machine governing
the actions. Then basically, when you transition from the submit
to the submitting states, there is no submit event on
or submit transition on the submitting state. So when that
event happens, according to the rules of state machines, that
event will do absolutely nothing. And that's by mathematical definition.

(14:19):
It's not by bullyan checks or some defensive code or anything.
It's just the mathematical definition of how state machines work,
where that event basically has zero effects. There's no transitions taken,
nothing will happen. So it does make your code a
lot more robust because you can be certain that in
this state when that event happens, you know, we won't

(14:41):
get any unexpected transitions and we won't end up in
unexpected states. Now, the other angle for impossible states would
be that whole I like showing this insides but this
funny image where it's like error success and it's like, wait,
how can it be both an error and a success.
So because state machines say that you can only be

(15:03):
in one state at a time, it prevents you from
being in that sort of multiple states, you know, weird
Twilight Zony sort of you know, states and you might think, well,
this never happens in apps. Definitely does, Like I'm sure
that you've seen the loading spinner on an app and
an error shows up in the bottom corner as a toast,

(15:25):
but the loading spinner is still going, and you're like, well,
how could it still be loading if it definitely failed? Like,
I'm sure you've seen this many, many, many times. State
machines prevent that just by definition, Yeah.

Speaker 2 (15:37):
Because I think I feel like that that the situation
you just described as like very symptomatic of like asynchronous programming,
where especially with like an observable stream where you failed
to handle something. And so okay, so I'm going to
take that to pivot to how do state machine genes

(16:00):
work in Angular? And I know that's a very broad topic,
but like, like I know how your works in Angular,
So how do like how do Angular programmers start to
implement state machines in their applications?

Speaker 4 (16:18):
So, yeah, that's an interesting topic. First of all, disclosure,
I'm not really a big Angular developer, but I am
aware of like just the you know, the developments that
happen in uh, you know, supporting x date in Angular.
And what's actually funny is that we do have a
lot of I guess you could call them adapters or
integrations for using x date with different frameworks, or well

(16:40):
libraries whatever you want to call them, like reacts, view, spelt, solid,
et cetera, even stencil, but we really haven't had one
for Angular, and there have been some efforts, but we
just didn't make it yet. But the thing is, there
are a lot of developers who use x date with Angular,
honestly because it's a lot easier to just use it

(17:01):
directly than to have some sort of adaptor. It's very
interesting how it works, but just Angular makes it very
friendly for people to just start using xtate, and I
think that's for like a couple of reasons, one of
them being the fact that Angular or sorry xtate actors
are already subscribable, so you could definitely just do convert

(17:23):
that to an RXGS stream. But they also act as
sort of as singletons, so you know, you could just
you know, have it in your class, your your component instance,
and it just works. Just call it dot send and
then send an event and then yeah, everything just works
as is.

Speaker 2 (17:42):
I feel like this is the first time I've ever
heard anyone say the basic library just happens to work.

Speaker 4 (17:49):
It's yeah, it's surprising, but from from the very start
we did base it on or not from very start,
at least from version three, we based it on just
being RXGS compatible, just because I really like and appreciate
the ARTSJAS library. But also you could think of these
these state machine actors as observables plus plus, so they're

(18:11):
not just something that you could subscribe to state changes from,
but there are also something where you could send events to.
So it's sort of like a behavior subject the sort
of thing.

Speaker 2 (18:21):
Yeah, and you know, it's funny that you say that
because a lot of times I think of observable streams
that I've composed, right using composable operators as machines that
manipulate state. So like event comes in with the state,
things happened to that state, new state comes out like

(18:42):
so interesting, right.

Speaker 4 (18:44):
And yeah, in the past I used the scan operator
a lot just because you know, it works essentially the
same way, where you have a stream of events, you
have an initial state, and this scan operator you could
define like, hey, this is what happens when you're in
this state and this event comes in. This is how
that state is transformed and honestly, state machines work pretty

(19:05):
much the same way.

Speaker 2 (19:07):
Yeah, and the scan operator again is one where it
just it has your initial state and then your outputs.
Like it, you could make a rudimentary and grx implementation
using the scan operator. So yeah, because it does it
past takes. Yeah, awesome. So okay, we talked about x state.
So what is X state.

Speaker 4 (19:28):
X state is a library for state machines, state charts,
and actors, so those three main things. At first, it
started with state machines and then it sort of expanded
into state charts, which is a really interesting extension of
state machine, which was created by David herrel In I

(19:50):
want to say nineteen eighty nine. Yeah forgetting when that
paper was written, but it was part of UML. You know,
state machines and state charts, and then actors. Actors are
sort of like the singletons where you could basically have
state machines as the logic for that actor, and an
actor can receive events, send events to other actors, spawn

(20:14):
other actors, et cetera. So it's a very powerful wave
of programming. And these are also really really old concepts
going back to the nineteen seventies and eighties. Yeah, so
x is a library that allows you to basically define
that logic and orchestrate actors within your front and applications
or even in the back ends too. Nice.

Speaker 2 (20:35):
Okay, so x state would work with like a no
JS type. Yes, yeah, nice. So it sounds would like
would state machines? Would they be considered a form of
like functional programming or is it ease? They're so they're deterministic,
and it sounds like it would given the same inputs,

(20:58):
it should always have the same output.

Speaker 4 (21:02):
Yeah, in a way it can be. It's it's not
strictly functional. It's sort of its own things. So when
you create an actor, which is sort of an instance
of a state machine, so an actor has its own
you know, identity, and it's not exactly pure because it
has its own internal states, but its logic or its
behavior is governed by this state machine, which again you

(21:26):
could think that as a transition function, and ideally this
transition function is pure. That's the biggest constraints of state
machines is that you know, given a state in an event,
you always have a next state, and you know, maybe
some effects as well or actions that are executed along
with that. But they're not executed as part of the transition.

(21:49):
It's sort of returned as in, hey, these are the
actions that should be executed. So in a way, you
could use it in functional programming still pure, but it's
not a strictly functional programming.

Speaker 2 (22:00):
Okay, yeah, it sounds like it would work very well
with I mean, like I know a lot of older
angular applications, legacy applications. Uh, they're very imperative where it's
like do this, then do this, do that, do this,
and you're trying to micromanage like every little thing that happens.
And I know before you know, like within the last

(22:24):
five or six years, there's been a push to be like, okay,
let's be more reactive when we program, like, let's use
functions when we can as opposed to trying to manage
every little thing that happens. And so it feels like
it would fit into that ecosystem very well. So when
people are deciding how to manage state in their application,

(22:48):
when would you recommend reaching for a state machine.

Speaker 4 (22:52):
For simple applications where you know, you don't have complex logic,
like you know, basically crowd applications things like that, you're
just catching data showing it, et cetera. You don't necessarily
need a steam machine. It's when things get more complex
that you know you should reach for something that's similar
to a state machine. So I always say that, like,

(23:14):
if you have something that could exist in different states,
then stop just throwing bullion variables at it, because honestly
they might be the most convenience, but they're actually the
wrong abstraction. So I see a lot of time when
people are trying to manage, Oh, we're fetching lots of
data in different steps. We might have is on step one,
or is loading step one, is loading step two, et cetera,

(23:35):
and just all of these bullion variables. Especially if you
have something like is loading, is success, is error, they
might think like, oh, okay, yeah, so if we're in
the success state, then is loading is false? Is success
is true, and is error is false. But actually, because
they're bullion variables, you have two to the power of three,
which is eight different possibilities where you could have loading

(23:58):
and success true, an error true, or even all three
of them true or all three of them false, and
all of a sudden we go back to that impossible
state thing. So I say, a good foray into starting
to think in terms of state machines is just using
a simple string NU, so getting rid of the habit
of using boolean variables and instead having a status variable

(24:21):
like that's it just status loading, status error, status excess.
So now you're adhering to one of the main principles
of state machines where you can only be in one
state at a time, and so it's a really good
way of thinking. And then the next step, of course,
is using events, so instead of just directly manipulating states,

(24:43):
which there's so many ways that this could go wrong,
and even if it doesn't go wrong, your logic just
is all over in place. It's not centralized.

Speaker 2 (24:51):
Yeah, those are hard to maintain apps, so right, which.

Speaker 4 (24:55):
Is why you know things like NGRX exist, etc. The
scan operator like we were talking about, like centralizing your
logic might be a little bit indirect and less convenience
because you can't just say, oh, when this button is clicked,
change this state, but instead, when this button is clicked,
dispatch an event somewhere and then let somewhere central handle it. Again,

(25:17):
a lot of developers might be against this, think, oh,
it's very indirect, but you're centralizing that logic. You have
only one place to look for that logic, and it's
just extremely convenient. So that would be the next step,
you know, using like an enium status variable, using events,
and then eventually, if things get really really complex, then

(25:40):
xdate is there to help because xdate allows you to
describe these state machines in a way that can be visualized,
a way that can be serialized. And furthermore, you could
describe state charts, so you could have states that have
nested states. You could also have parallel states, entry and
exit actions, history states, just a lot more things that
come with state charts. And then you could also transform

(26:03):
those into those actor entities which you could just pass
around and send events to and subscribe to. And it's
just very convenient. And so I would say if you
find yourself just I guess building all of that yourself,
where you're realizing, oh, I need something where I could
subscribe to it, send events to it, et cetera, then

(26:24):
maybe reach out for X state because it's already done
all of those things for you. I would say, don't
reach for xaate first. Nimple logic at first, because it's
sort of like using a jet airplane to travel two
miles down the road. You don't really need it look cool,
but exactly exactly, but yeah, it's there when you need it.

(26:48):
And honestly, I always say that the concepts are more
important than the library. Just knowing what state machines are
and knowing what the actor model is, event driven programming
and all of that, and X state is just one
implam of it. There's no reason you can't just implement
the basics yourself if that's all you need.

Speaker 2 (27:05):
Yeah, it sounds I mean, this sounds like what the
Angular community has been preaching for years now, which is
like just kind of I think when I started digging
into why it's hard for people, I think it's because
our brains tend to do things like I push the button,
and now I need to do this, and I need
to do this, and I need to do this, and
it's hard to have the faith to say I pushed
the button and then let everything else do the things

(27:27):
that It's like I'm just sitting here waiting for the
button to get pushed and then I'm going to do
my thing.

Speaker 3 (27:32):
You know.

Speaker 2 (27:32):
It's like it's hard to like have the faith to
set up those systems that just kind of flow through.
But once you get that mental model in your head
of like, oh, that's what I'm doing, it's so much
easier than to program next. You're like, the button doesn't
have to care what happens next. The button just has
to say somebody pushed me, you know, and then other

(27:55):
things know what happened, like it's not your problem button.

Speaker 3 (27:58):
Yeah, exactly.

Speaker 2 (28:00):
Yeah.

Speaker 3 (28:00):
And also for for like modern applications as well, we
have a ton more interactions, not just clicking the bunt.
Maybe some key some key binding like control as a
command as happening, or we have the auto saves running
as well. Right, all of those can you can talk
to centralized logic location and just say the samivan probably yeah, And.

Speaker 4 (28:23):
Honestly it man, I'm really glad that you brought it up,
because it, like, just doing things in an events based
way makes it very very easy to decouple your logic,
you know, just work on the components without having to think, oh,
what's the logic behind it? Uh? For example, you mentioned
key bindings. So let's say that you know, you have
a you're making a video player app, and you have

(28:44):
a plate button, and so in that plate button you
have logic. So you know, maybe load the video, play
the video, et cetera. And then APM comes and says, hey,
we actually want them to you know, if they press
space bar, then it should also do the same thing,
play the video. So what do you do? You copy
paste as a developer right into that event handler. And

(29:05):
then again they say, hey, we actually want this video
in this situation to AutoPlay after five seconds. So you're like, okay,
I guess that logic there too, And then let's bug
in the logic. Are you going to remember all those
three different leases in the logical change?

Speaker 2 (29:22):
No?

Speaker 4 (29:22):
So I also point people to physical calculators. So if
they were to open it up and look at each
one of the buttons, the buttons don't have a little
computer or microprocessor inside each one of them. It's a
very simple like you know, you touch it, it sends
an electrical signal to somewhere central the same thing, right,

(29:43):
And also, pressing a button might have multiple different effects
based on what state you're in. So pressing the space
spark might play a video, it might also positive video.
It might also just do something else like that's why
just you send an events the space was pressed and
something else will handle it. It makes it very very

(30:04):
easy to just, uh, you know, change your components around
and just handle all the logic in one place.

Speaker 2 (30:11):
Yeah, yeah, exactly, and we I mean I come from
like I used jr X a lot, but it's kind
of the same concept of you can have an effect
or reducer get triggered by any number of events, Like
it doesn't have to be like it could say, my
space bar got pushed or M got pushed, or I
clicked or I rolled over, and all of those things

(30:33):
can trigger the exact same actions to happen. And it like,
once I figured that piece out, I was like, oh gosh,
this just got so much easier because, like you said,
you're then finding to make changes. It's in one place.
I only write tests once, Like I can write a
test and then I can just make sure all the
actions trigger it like I think it should, and you know,
it just makes all of that so much easier. Yeah,

(30:58):
it sounds like X state fits in really well with
it sounds like it's I mean, obviously it's different, but
it's not like so wildly different that that it's requiring
you to come up with a whole new mental model
of how to manage events in your application. It sounds
like the event management part of it is very similar

(31:19):
to what if you're doing n g X or any
event driven development in Angular, that's you're going to at
least have that concept it at hand.

Speaker 4 (31:30):
So nice, right, Yeah, so.

Speaker 3 (31:36):
I'm gonna move on to let's say that. Okay, we've
talked about state machines, how good, what situation they good for?
And we let's say we accept the trade off of
state machines as well in directions a lot of stuff. Now,
how do on like guests started with X stage which

(31:57):
brand new or with assisting do we go with the
visualizer first or should we try to visualize our state
machine first before starting with code or what is your
recommendation here?

Speaker 4 (32:11):
See, the visualizer is there to there to help you.
And by the way, our visualizer is at states dot new.
It's completely free to just sign up and start using it.
And yeah, you could just drag things around and then
generate the code, copy paste the code, or even just
open it up and stack Blitzer code standbox. So that's

(32:31):
one possible way where you could start. I would say
another thing too, just because, to be honest, actually is
a pretty big learning curve. This is something that I
hear pretty often, and that's because all of the concepts
that you know, not only state machines, but state charts
in the actor model, there's a lot to take in
and a lot of developers feel like they need to
learn all of that, which takes a very long time

(32:52):
before they could start using it, which is not true,
and that's actually why I recently created. It's called X
state Store. So it's a store just like you know,
just like ngrx's or reducts or zoos stands, just very simple.
You define your not necessarily finite states, but you could

(33:13):
define what's called context in which that's where you store
all of your data and then you send events to it.
So the API is extremely similar to x state, but
it is a lot more limited in that it basically
is at feature parity with all of these other states
based libraries. It just has a very similar API to
X state, so that if you need it to, you

(33:34):
could migrate to X state and it actually the whole
point is for you to once your logic gets to
that threshold of complexity, you can migrate from X state
store to X state. But I would honestly recommend people
go there because you could learn x state store in
five minutes, if not less. Just copy and paste the
example and that's all you need. It's a single dependency.

(33:57):
And yeah, so I would say definitely start there.

Speaker 2 (34:01):
It looks really pretty Yeah, it looks pretty straightforward. I'm
looking at the docs now, and it's just creates store,
an object to find out some functions that happen on
different actions.

Speaker 3 (34:16):
Yeah, yeah, yeah, I just looked. I just looked at
it as well. It reminds me of the reductx toolkit,
like great slice, very similar to that.

Speaker 4 (34:26):
Yes, yes, it is very very similar to that. Trying
trying to think of some differences. I haven't looked at
Redux toolkit in a while, but yeah, they are going
to be very very similar. And also the store that
you create is also subscribable, so you could just dot
subscribe to it. And yeah, so it fits pretty well
into Angular applications. It definitely has the same idiosyncrasies as rxgs.

(34:50):
With dot subscribe, they return to a subs subscription object
where you could call it dot unsubscribe and and yeah,
just send events and see the store update. And also
I also added an event emitter to it as well,
which is extremely useful because another One of the main
tenets of x date is declaratively saying when effects should happen,

(35:16):
such as actions and not just the state changing. Because
we know that the state changing is only part of
the story. Applications would be entirely useless if there were
no side effects, so you know, we need to manage
those somewhere. And I don't think that it's right that
we decouple date in effects because they sort of go

(35:37):
hand in hand. And so this allows you to do
amidst these events that could be listened to. For example,
you could emit a changed events and then say when
it's when the change event happens, do this effects you know,
submit the form, et cetera, or persist it and yeah,
so it also includes that event emitter as well.

Speaker 2 (35:58):
Nice. Nice, Yeah, that's I think that's so true. It's
I I read stuff where people are like, oh, if
you if the word effect is in it, it's it's
probably the wrong you know you're doing something wrong. I'm like,
I don't know, Like there's actually side effects that have
to happen, like logging or like you said, form submission,
data persistence where it doesn't really necessarily affect the state

(36:19):
of the app like in a happy state on a
form submission, it should just be like I did it.
I submitted the form and I don't really care about
anything else as the application. So yeah, like there's definitely
or logging, Like my applications shouldn't break if I can't log.

Speaker 4 (36:34):
So like exactly. So yeah, so this provides a declarative
way for you to, you know, to have these effects.

Speaker 2 (36:43):
Nice. So if a person has an existing application and
they've they've gone through the X State store and how
you said it's fairly easy to go from X state
store to full X state or is a fairly like
I know, yes, I keep bringing up n JR X

(37:05):
because that is honestly the thing. I know, Like we
have like component stores, and going from component store to
the global store isn't always straightforward. So but you said,
so jumping between X state store and X state is
a more simple is fairly straightforward?

Speaker 4 (37:24):
Yeah, because essentially it's a it's a very very similar II.
You know, you're you're basically just changing where things are imported,
and then all of a sudden you have all of
the full features of X states available to you.

Speaker 3 (37:36):
Nice. Yeah, And by the way, Lara, just I just
want to point out real quick is that x state
is not necessary because you make the comparison between component
store and global store. For x state store and x state,
X state does not necessarily always singleton. I mean, like
the state machine is you you describe it once, but

(37:58):
the actor you can spawn actor and uh you can
you can spawn the actor when you initialize a new
component uh so so so so it's kind of like
not singleton in that sense. So just so you can
still use x stay fully, but it doesn't have to
be a singleton, right.

Speaker 4 (38:19):
Yeah, I'm glad you brought that up as well. Because
with x date we we have this concept of actors
and so again each actor is like an entity. Uh
and this these entities just like a class instance. It
holds its own states and then you know, just updates
the state when events arrive or sorry, when it receives
the events. And because an actor is just an object,

(38:44):
you could think of it as an object with dot
send and dot subscribe and that's honestly pretty much it.
You can also call dott snapshot, which just gives you
the latest uh you know, snapshot that's going to be
uh emitted anyway when you subscribe to it. But these
opjects can live anywhere, so you know, like you were saying, uh,

(39:05):
it's something that you could have at a component level,
you could have it at a global level. It's it's
just an opticts, so it's there, use it however you
want pass it down to other components. It's really really
flexible in that regard that.

Speaker 2 (39:20):
Follows the rules of like dependency injection, where like depending
on where you inject it, that's where it the level
that it is available at in the tree.

Speaker 4 (39:31):
I believe, I believe, so, yeah, like at least from
a from a react perspective, like yeah, if it's deep
down in the tree, then you could, you know, in context,
you could see it in other components. And I believe
that it's the same thing with Angular zoom.

Speaker 2 (39:45):
Yeah, yeah, we have like this. We have the environment
injectors and the component injectors, which is like the weird
thing about Angular that is like easy to not be
aware of unless you've actually dug into dependency injection. And
I'm bitten by it. But yeah, okay, yeah that makes sense.

(40:06):
That's it sounds very flexible. Okay, So if somebody is
learning X state, in your opinion, what is the hardest
concept for people to get their heads around.

Speaker 4 (40:16):
Oh, good question. It honestly depends who you are, so
in my mind, especially if you're coming from reducts or
you know, n g r X, it's pretty simple because
you could just say, oh, yeah, it's a it's basically
like this redus like approach, but with with well defined
you know, states and transitions that I could actually visualize.

(40:38):
Some of the learning curves involved just the different parts
of state machines that you might not need anyway, So
things like parallel states, where you know, you might be oh,
I thought you could only be in one state at
a time. Parallel states describe combinations. Yeah, yeah, they describe
combinations of states, but they do it in a way
where you don't have this combinatorial explosion. To give you

(41:01):
an example, if you go to like, let's say, Chipotle,
which is a Mexican Ish restaurant for those who are
listening in non the United States, unless you're global, I'm
not sure, but anyway, Chipotle, it's it's great because you
could say, hey, I want this meat and these means
and that's However, if you go to like a normal
Mexican or Chinese restaurant, then you have a menu that's

(41:22):
like three or five pages long with every single combination
of these same ingredients. So it's like which one would
you rather read, like just six things where you just
choose what you want, or one hundred and fifty different
things where it's like just a combination. So parallel states
just allow you to say, hey, yeah, this is a
combination of these six different things. So there's that history

(41:45):
state sometimes like actions where it's it's not just transition actions,
but also when you enter state, exit the state, and
knowing the order of these actions. So all of these
are Honestly, it's a lot of baggage from the original
definition of the state charts when it was created in
nineteen eighty nine, and not much has changed since then.

(42:08):
So but honestly, people don't really need to know all
of that. But the biggest learning curve is probably just
the change in the way of thinking where you're not
directly manipulating states. You're sending events, you're subscribing to state changes,
and there's the whole actor model of each actor has
its own internal state. Actors can communicate with each other

(42:30):
and all of that. So, yeah, if you use actually
in a basic way there's really not much learning curve,
but if you get deep into it, then with some
of the features, there is a bigger learning curve.

Speaker 2 (42:43):
Yeah, that makes sense. It sounds kind of like RXGS itself,
right the Yeah, you know, you can get by with
RXGS honestly, as long as you know how to subscribe
and unsubscribe, you can get values out of it. And
then if you learn a couple of operators, then you're like, okay,
now really accelerated. And then you find out there's like
three hundred some you know, like there's less number of operators.

(43:05):
Were like, oh no, I don't know all these. It's
like it's okay, you probably won't use any of them,
so exactly. Yeah, nice, nice for the like what you
said that the concept has been around for a while.
Is there anything about the concept that is changing, Like

(43:26):
I know that we have you know, like signals has
come into this scene for sort of managing state in
your application sort of at the presentation layer. Does that
affect X state in any way? Is that is that something?
Is there something else on the horizon that X state
is considering.

Speaker 4 (43:47):
Yeah, so two things. First of all, the proliferation with
signals and not only angular, but other frameworks too, popularized
by solid, used by Spelts, et cetera, and well, actually
just originally by view you has. You know, really they
didn't call it signals, you know, but we just ran
with it. Yeah, exactly exactly. But so signals are a

(44:09):
very interesting concept from an optimization point of view. They're
extremely useful since with well, when a part of your
states changes, you could basically subscribe at least implicitly to
that part of the state and only rerender things when
when that part of the states changes. If they're using
that part of the states, obviously this doesn't work, and

(44:29):
react react it's just like, okay, something change, let's rerender
the entire component and all of its children and hope
for the best. That's just you know, React is very
much an outlier there. But the in my opinion, the
problem is that diignal if you directly, it's a little
problematic because you're directly manipulating states. So there's this, you know,

(44:54):
chance that just like the problem I was talking about before,
if one part of your app is directly manipulating it
one way, but the other one is directly manipulating it
another way, you're going to get into impossible states. You're
not going to know why this change happened because signals
inherently don't have this way of tracking, like why did
this part of the state change? It just knows it changed,

(45:16):
let me tell you about it, so that you could
react to it. But there's no there's that loss of
data for that, you know, the events, the events is missing,
so and that way it's a little bit bad. But
I think that signals, at least as an underlying mechanism
for state changes is still very useful because in X state,

(45:37):
the state objects which includes the state value which is
the finite state value, but also the context which is
all the other data. You could actually sort of treat
that as you know, in a signal based way, where
if a part of that state changes, then only render
this part. That is definitely possible, again as an underlying mechanism,

(45:58):
but not as a manipulation sort of thing. So yeah,
I think that there's a future where signals and X
states do work together. The other thing is that for
the longest time, and you know, we were going to
get into AI things like that, but for the longest time,
X state had a very rigid API that was based

(46:21):
on you sort of had to define your state machine
structure in a JSON serializable way, and so instead of
having normal if statements or foreloops or things like that,
you had to do this like guard object and then
like this action's array, and then you had to have
like this targets and then also have that the objects.

(46:42):
So basically it's sort of like a DSL, which, sure
it might be universal so that you could use the
same state machine in other languages. But the problem with
that is it's sort of a very unnatural way of programming,
I will admit, but it was basically the only way
to get it so that you could use that in
your applications and visualize it at the same time. But

(47:05):
now that lllms have come along, you know, I've been
experimenting with let's say that you know, when a state
transition happens, you just had a really natural way of
maybe adding an if statement, adding a four loop, just
calling some effects and then returning what the next state
should be, and just a normal function, which is very
intuitive to write. So before it wasn't possible to do

(47:27):
that because you lose all the visualization abilities, all of
the deterministic everything. But with LLLMS, we could easily just
understand the intent of that and visualize in the state
machine what that function is doing. So it could basically
convert your plane function into well, this is a guarded
transition with these effects and we're going to lit them

(47:49):
out and yeah, so it it becomes possible to write
x state in more natural code, and that's something that
I definitely want to explore for version six and just
continue to destroy the learning curve so you're just writing functions,
you're not having to think about the DSL anymore.

Speaker 2 (48:07):
Yeah, that's great.

Speaker 3 (48:08):
Yeah, that's great. Now you mentioned AI, I was gonna
mention AI because I'm gonna be honest. If I'm learning
x state today, I would probably take my assistant system
and go to like a AI website, like a vote
dot new Hey vote, here's my assistant system. Can you
convert it to x state?

Speaker 4 (48:28):
Now?

Speaker 3 (48:28):
The problem with that is that there will be good
machines that the AI could write, but they can also
write bad machines. So do you have any suggestions or
recommendations to like pick out the bad pattern in the
machine and the tastes to state machines so that we
can collaborate with the AI to have good machines.

Speaker 4 (48:49):
Yeah, it's a little bit tricky because if you're asking
AI directly, there's actually a lot a lot of like
X state version four and below examples in the I
guess the AI repertoire like its corpus of knowledge, so
it will return you something that looks very similar to
AI or sorry, X state version four and if you

(49:12):
want to actually be five like depending on the model,
you might be out of block or it might be
able to generate it for you. We only released it
last year, so it's I think it's been less than
a year since it's been out so far. Maybe maybe
two years. I don't know, timeplies anymore. Yeah, but at
stately dot AI, you are actually able to generate machines

(49:33):
based on playing descriptions, and it will do its best
to basically take if it's X eight version four, make
sure that it's formatted in a way where it's compatible
with x state version five, and you know, maybe in
the future we'll have fine tuned models that do that.
But I will say that AI is actually pretty good
at generating these state machines regardless. So even if you

(49:56):
have to do some minor tweaks to make it work
with the latest version of X state. It does generate
you know, pretty comprehensive state machines, just because there are
so many open source examples of it that it knows
how to generate that nice.

Speaker 3 (50:10):
Nice.

Speaker 2 (50:11):
Yeah, yeah, that's very helpful because it is a tool
that people lean on more and more than and I
feel like the tools are starting to get more mature
to where you're like, Okay, this actually feels like a
useful tool instead of just like give me twenty five
dad jokes or something.

Speaker 4 (50:30):
You know, exactly.

Speaker 2 (50:32):
Yeah, that's great. Well, we're getting close to the end
of the episode. Is there anything else that you would
like our listeners to know about X state or state machines?

Speaker 4 (50:46):
Oh? Well, we do have a discord so discord dot
gg slash x states and there you could ask all
of your x state questions and I try to provide support,
you know, as much as I can and just talk
about state machines and state charts in general. There. So yeah,

(51:07):
there's that. We have a lot of resources at stately
dot ai slash docs and it looks amazing.

Speaker 2 (51:13):
I'm gonna definitely spend some more time in there today.

Speaker 4 (51:16):
So yeah, and again, if you want to get started
just making steam machines visually and converting them to code.
You could just go to state dot New It's free,
so go for it. Nice.

Speaker 2 (51:27):
Nice, Well, thank you so much for joining us today.
And you said that you are David K. Piano all
over the place, all over Are you on blue Sky?
That's fine?

Speaker 4 (51:38):
I am on Blue Sky, Yes.

Speaker 2 (51:40):
Yeah, it feels like that seems to be where my
tech crowd has migrated, which has been in large.

Speaker 4 (51:48):
Yeah.

Speaker 2 (51:49):
Yeah, it's been really great because I definitely I spent
a good year on LinkedIn trying to relive the good
old days of Twitter. But so right, but yeah, well great,
So people can reach out to you there nerd out
about state machines or x state on blue Sky, on

(52:10):
on LinkedIn, on any social media platform, and yeah, I
think that's all the questions that I well, I actually
have like a thousand more questions, but that's just that's
what I'm like, but not necessarily specific to X state
or machine state machines. So thank you so much for

(52:30):
describing the concepts to us, introducing us to X state.
Some of us obviously already know X state and state machines.
Not everybody is me so, but Thank you so much
for your time today, and to our listeners, thank you
for joining us. If you like the content that we
have on the podcast, please be sure to subscribe wherever

(52:53):
you get your podcasts from and we'll catch you next time.

Speaker 5 (52:58):
Hey, this is Pressed the Mine, one of the NGI
Champions writers. In our daily battle to crush out code,
we run into problems and sometimes those problems aren't easily solved.
NGCOMF broadcasts articles and tutorials from Angie champions like myself
that help make other developers' lives just a little bit easier.
To access these articles, visit medium, dot com, forward Slash NGCOMF.

Speaker 1 (53:20):
Thank you for listening to the Angular Plus show in
CHICOMF podcast. We'd like to thank our sponsors, the NGCOMF
organizers Joe Eames and Aaron Frost, our producer Gene Bourne,
and our podcast editor and engineer Patrick Kays. You can
find him at spoonful Ofmedia dot com.
Advertise With Us

Popular Podcasts

New Heights with Jason & Travis Kelce

New Heights with Jason & Travis Kelce

Football’s funniest family duo — Jason Kelce of the Philadelphia Eagles and Travis Kelce of the Kansas City Chiefs — team up to provide next-level access to life in the league as it unfolds. The two brothers and Super Bowl champions drop weekly insights about the weekly slate of games and share their INSIDE perspectives on trending NFL news and sports headlines. They also endlessly rag on each other as brothers do, chat the latest in pop culture and welcome some very popular and well-known friends to chat with them. Check out new episodes every Wednesday. Follow New Heights on the Wondery App, YouTube or wherever you get your podcasts. You can listen to new episodes early and ad-free, and get exclusive content on Wondery+. Join Wondery+ in the Wondery App, Apple Podcasts or Spotify. And join our new membership for a unique fan experience by going to the New Heights YouTube channel now!

The Breakfast Club

The Breakfast Club

The World's Most Dangerous Morning Show, The Breakfast Club, With DJ Envy, Jess Hilarious, And Charlamagne Tha God!

Fudd Around And Find Out

Fudd Around And Find Out

UConn basketball star Azzi Fudd brings her championship swag to iHeart Women’s Sports with Fudd Around and Find Out, a weekly podcast that takes fans along for the ride as Azzi spends her final year of college trying to reclaim the National Championship and prepare to be a first round WNBA draft pick. Ever wonder what it’s like to be a world-class athlete in the public spotlight while still managing schoolwork, friendships and family time? It’s time to Fudd Around and Find Out!

Music, radio and podcasts, all free. Listen online or download the iHeart App.

Connect

© 2025 iHeartMedia, Inc.