Transcript from the "Getting Set Up with XState" Lesson
>> In the first exercise, we learned how to model this simple state machine using either a switch statement or by using an object. And so now we're going to be taking this to the next level. And specifically focusing on this object, and using this to actually implement a state machine using the XState library.
[00:00:21] And so if you go to xstate.js.org/docs, this is the XState library. And the installation and quick start are all on the homepage over here. So you could npm install xstate, and then you create a machine using createMachine. And you interpret the machine, which makes a live version of that machine, which persists state.
[00:00:47] And is something like that object we talked about in the first lesson, where you could send events to it. And so when you create a machine, the object syntax that we put inside of here is going to look exactly the same, or at least pretty close, to what we did in the first lesson.
[00:01:05] Now the quickest way to get up and running with XState is actually by using the Visualizer. So if you go to stately.ai/viz, you're gonna be greeted by this homepage, where you can see an example or just start coding right away, which we're going to do. And so if I create a machine, I'm actually going to copy this entire object, and I'm gonna put it inside of createMachine over here.
[00:01:33] Let's see, const.machine = createMachine. And so when I press Cmd + Enter, or if I click Visualize over here, now you're going to see the state machine visualized in the visualizer. And so it's going to look pretty much like the diagram that we just drew over here. So we have a loading, playing, paused.
[00:02:18] And I definitely encourage you to try it out. So, again, if you wanna get started with XState, you would do npm install xstate. And we're are going to be using the createMachine and interpret functions from XState. And so, yeah, just gonna show you how that works real quick.
[00:02:41] We're gonna be jumping into exercise number one, just to show you how all of this works. And actually, exercise one is all ready done, so yeah. But if you wanna do it yourself, then please feel free. What should really happen over here is like this should be empty, so yeah.
[00:03:07] Okay, so for this exercise, what you're supposed to do is create a machine using XState that matches the state machine that you created in the previous exercise. So just to give you a quick intro on that, I'm gonna jump into the scratchpad over here. And let's clear some stuff out.
[00:03:42] All right, so we're going to import a couple things from Xstate, gonna import createMachine and also the interpret function. For now we're just gonna be using createMachine. And so we're gonna be creating a machine using createMachine, saying that a lot. And this machine, the object inside actually doesn't need to take anything.
[00:04:06] This is a perfectly valid state machine, even though it's completely empty. So if we console.log the machine.initialState, you're going to discover what exactly is in that state objects that we have. So the initial state is created by, let's have initial state of loading, so states, loading. All right, so our initial state is going to have a few important things.
[00:04:43] First of all is the value, just like we talked about, this value over here of loading. And so this represents the finite state of the machine. There's also going to be an event over here, and that represents the events that caused the transition to this state. In this case it's just an xstate.init event, which is an internal event.
[00:05:04] And there's also going to be context, which we're gonna be taking care of in a future lesson. But for now this value is the important part. And yeah, so when we have this machine inside createMachine, we actually have the transition function built into this machine. So we could say const nextState = machine.transition.
[00:05:35] And so just like we did before, we could specify undefined as the first argument, and we could give it an event. So let's say that we have two states, loading and loaded. So we say on LOADED: 'loaded', that's actually pretty redundant. Let's call it SUCCESS just for the sake of this example.
[00:05:58] And so we're gonna send type: 'SUCCESS'. And we're going to console.log the nextState. All right, so now we see that we have a state with value of loading. And when we send that event, now we have a state with value of loaded. So we see the event in the state object, and we see the value of loaded also within that state object.
[00:06:30] Now this state object has a couple of other features as well. So one feature that's going to be useful in our application is matches. So if I say console.log(nextState.matches, and we say loaded, this should be true. And so this gives us an easy way to match and make sure that we're in the expected finite state.
[00:07:02] So we have true over here. If we have something else, then it's going to be false. So you can use nextState.matches. Just like we did before in the first lesson, we created this sort of object that lets us send events to the machine and also we have a way to persist the state.
[00:07:25] There is a built in way to do that in XState as well, and that's by using the interpret function. And so instead of this, we're gonna be creating what's called a service. And again, this is just convention. But this service is going to take that machine that we created, and we have to call start in order to start the service, and say, I'm ready to accept events.
[00:07:51] Now, we could listen to events on the service by calling service.subscribe. And we are going to console.log the state.value. And we're also going to expose the service on the window, so window.service = service = service. All right, so right now the service immediately told us that we're in the loading state.
[00:08:23] So if I send type: 'SUCCESS', we called it, now it's gonna tell us that we're in the loaded state, just as we expected. So now we see that everything is working and it's all good. So interpreting the machine to create these services is really useful. And you could use this essentially as an event emitter in your application.
[00:08:51] And it becomes something that you could send events to, subscribe to. And those two things alone are really powerful, and it's what's going to drive the entire media player application.