This course has been updated! We now recommend you take the State Machines in JavaScript with XState, v2 course.

Check out a free preview of the full State Machines in JavaScript with XState course:
The "Interpreter Solution" Lesson is part of the full, State Machines in JavaScript with XState course featured in this preview video. Here's what you'd learn in this lesson:

David live codes the solution to the interpreter exercise.

Get Unlimited Access Now

Transcript from the "Interpreter Solution" Lesson

[00:00:00]
>> Let's talk about exercise number three. We have a little bit different logic than we did in the first two exercises, where we're still going between an inactive and an active state. But now we're doing it based on two events. Whether there's a mousedown event, we go from inactive to active, or there's a mouseup event, in which we go from active to inactive.

[00:00:23] So let's go ahead and create that machine. So our initial state is going to be inactive, just like the previous machine, and we're going to have two states. We're going to have inactive and active. And so in each of these two states, We could have an event that transitions between inactive and active.

[00:00:57] In the inactive states, when we have a mousedown event, we go to active. Again, this is using the shorthand syntax. If we type target: 'active', it's the same thing. So on mouseup, we go to target: 'inactive'. Okay, the next step is we want to create our service. So we're going to be using interpret, which is already imported for you in order to do that.

[00:01:27] So let's do interpret, and we're going to pull in our machine here. Okay, so let's talk about the difference between createMachine and interpret. createMachine essentially creates a blueprint for how your machine is supposed to behave. You could think about it as creating a really, really fancy transition function that's pure.

[00:01:54] It doesn't keep any internal state and you could share it in multiple locations without fear of having its internal state changed because it doesn't have any internal states. Now, a service is an instance of that machine. So a service will keep track of its own internal state as you send events to it.

[00:02:14] So another way you could think of a service, like a singleton, with that machine's behavior. Okay, the next thing we're going to do is we're going to listen to state transitions and set that data state attribute, just like we did before, on the box element. So we could say, service.onTransition, and we get the state.

[00:02:37] So let's go ahead and console.log that state.value just to make sure that things are working. So we're gonna start the service over here, service.start(). And then we're going to be sending events over to the service. Now, we could send the mousedown event like normal. So we could say, service.send(), and we could either pass a string, or we could pass an event object.

[00:03:02] I prefer to be explicit, passing things as strings or using the shorthand syntax is really good if you're quickly prototyping or in a hurry. But in general use cases, you want to use full objects, just in case you want to add payload later or you have any other application logic requirements that will force you to use an object instead of just a plain string.

[00:03:24] So with service.send(), we are going to send an event of type mousedown. And we're gonna do the same thing over here. So we're gonna send a mouseup event when we get a mouseup event on elBox. So let's try this out. We're gonna go to Exercise 03, and we're gonna see, [COUGH] we're gonna see that the state is changing in the console.

[00:03:57] So when I hold down my mouse, it's active, but once I release it, it's inactive. So let's go ahead and put that state right on elBox.dataset.states, and we're gonna set it to that state.value. So now let's see what happens. Okay, cool, when our mouse is down, we're in the active state, and keep in mind I am holding my mouse down right now, and when I let go, it's in the inactive state.

[00:04:34] Now, one final note, DOM events, such as what we received from addEventListener, mousedown, are also an event object. Curiously enough, so if we console.log this event, we're going to see that we get a mouseevent, and it has a whole bunch of things. So you could consider this the event payload.

[00:04:58] But it also has a type, so if we go to type, we see that it's mousedown. Now this is great because we could use those DOM events directly inside service.send(). So instead of having to create a whole new event object, why don't we just give it the entire event?

[00:05:14] So we'll give it event. And we'll just send the events here, too. So now, you see, it works exactly the same way. And our code is pretty concise over here. All the logic is contained right up here. So that's exercise number three.