Check out a free preview of the full State Machines in JavaScript with XState course:
The "Guarded Transitions" 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 explains that guarded transitions are transitions that have a conditional guard called cond that determines if a transition is allowed. If the guard returns a falsey response, no actions are executed and no transactions are taken.

Get Unlimited Access Now

Transcript from the "Guarded Transitions" Lesson

>> Now we're gonna be talking about transitions, guarded transitions in particular. So guarded transitions are transitions that have a conditional guard, which is called cond, C-O-N-D, and that guard tells us whether or not we're allowed to take this transition. So if that guard returns anything falsy, then that means that no actions are gonna be executed and the transition is not going to be taken.

[00:00:32] So an example of this, let's say that you have a promise state machine. When you go from the idle to the pending states on a fetch request, you are waiting for something to come back. And that could be either resolve events or reject events. Now, remember, events objects can contain payload.

[00:00:56] So it might be useful to use guarded transitions to check that the payload in the events satisfy certain criteria or that our context itself satisfies certain criteria. So if we go to the original XState visualizer example over here, we could see that there is an action that assigns retries.

[00:01:21] And so these retries are going to keep incrementing in the states whenever we fail. So we see the retries are 0, but when we click retry it goes to 0, goes to 2, etc., etc. So if we wanted to add a guard here, we could say that, you know what, we're no longer allowed to retry if we have more than five retries.

[00:01:47] We could say, hey, you've tried this too many times. I promise you, it's going to fail, pun not intended. So reject failure retry, we could say that we want this retry transition to only happen if we have less than five retries. So to do that we specify a conditional predicate.

[00:02:12] And just like everything else, that conditional is going to take the current context and the events that it received, and we're going to return context.retries is less than 5. So we can have no more than five retries. So let's update this, and you'll see that we have a green cond over here.

[00:02:35] And it's green because the visualizer understands that it is currently truthy right now. And so if we reject, retry, reject, retry we're gonna see that that turns red after so many retries, and then we could no longer retry. So this turns red and we're no longer allowed to take this transition because the retries is five or more.

[00:03:00] Now this cond doesn't look too nice in the visualizer, which is why we could also serialize this condition as well, or this conditional guard. So we could say cond, noExceededRetries, naming things is hard. So we could specify in the guards over here noExceededRetries, and we could say this is what that means.

[00:03:31] So when you see a noExceededRetries guard, this is the guard that you want to check against in order to see if a transition can be taken or not. So let's update that, and now you will see over here it says noExceededRetries, and it's going to work the exact same way.

[00:03:50] To define the guard, it's just like we showed. You have the condition, which is cond over here, and you are returning true or false based on whether or not a condition can be taken. Again, this can be separated out into a function and referred to by that function, and then you could also specify that in the options.guards.