 Yeah, thanks. Over to you, Tejas. Yeah. Thanks, Arun. Hello. My name is Tejas. I work at Grammar, where we mainly narrate data insights as stories. So today, I'll be covering on how to use finite state machines for managing front-end state. But before that, a quick survey, how many of you are familiar with finite state machines? If you are a student, you probably might have covered UML diagrams just like flow charts. So those nice-looking flow charts are just not a theoretical, completely theoretical subject. They can actually be useful in the management of front-end state. And to illustrate that, and the problem that we will be solving, I'll start with taking the example. As we go on building a 2D side-scroller game, anyone recognize this game? Not Super Mario. It's Mega Man. We wouldn't be building this, but it'll be very similar from the feature standpoint. So firstly, we start with handling the game player's input. So we have a simple function called handle input. And whenever the button B is pressed, we set the image as jump. So B is to jump the player. And now, if you see the previous one, the player can only jump for one instance. So what's the issue with this piece of small code? The problem is we are not building a flappy board game, so there is no air jumping. So once the input is recognized as the B press, we should put a Boolean flag and ensure that further press of the button B, the player doesn't keep jumping in the air. So if the user keeps on pressing the button B, the player also should still be jumping only once. The rest of the button B presses should be discarded. So we add a simple Boolean flag called ease jumping and set the graphics image as jump image only if the player is not jumping. So we can move on to the next requirement. The next requirement would be to, whenever the user presses the down button, we have to duck the player if the player is on the ground. And on release of the down arrow, the player should stand. So how do we write the code for that? We start with one more refratement and say that if the input is pressed down and the player is not jumping, we set the graphics as duck, which means that if the player is standing, we basically set the graphics as duck image. And on release of the down arrow button, we set the graphics image as stand, resetting the image. And if you think this is correct code, you're basically wrong. There's still a bug in this. Any try guesses? Okay. So when, so if we take the previous, the first feature which is jumping and when we are jumping, if the user releases the arrow down arrow, then while the player is jumping, the image is set to standing in between the jump. So how do we again try to fix this? We add one more flag saying only jump if the player is already not jumping and if the player is not ducking. So, and we can keep doing this if we now wants to add a dive attack, which is a ground pound. We can add one more if condition in on press of the down when jumping, saying that set the graphics as image dive. So that's one more feature addition and that again breaks something. So this time it is when I'm, I can, so if I am doing the diving, so when I'm jumping from the height and if I press the button B again and again, I keep on air jumping. So again, I need to introduce a new flag called east diving and keep on adding more and more flags to the code. And this is the common situation that we all will be in whenever we start with the simple if statements. And we, and remember, we haven't yet even started writing code for a shooting feature. So keeping this aside, how are state charts going to be very much relevant in solving this? Before even understanding what a state chart is, we need to understand what a state machine is. A state machine is basically a data structure or a container that has a set of states. It follows a few rules, which is like a machine can only be in one state at any point of time and a machine takes a sequence of events as input. The way it works is it takes the input sequence of events as input, input plus current state, it will trigger change the state of the application to the next state. So these might be some familiar UML diagrams that you might have studied, which is like start state and state, a transition from one state to the other state. The other important thing in the practical applications is the usage of guards or conditions, because most of the practical applications will require conditional setting of states. Coming to the previous problem, we can actually rewrite the entire if statements code by taking a piece of paper and pen and jotting down the listing on all the states that the player could be in, which is standing, jumping, diving and ducking. And there were few transitions between these states which are limited to this. So what's the difference between this and the previous one? So here there is no air jumping. So if I have to create a feature like air jumping, I would have to add a self transition to the same jumping state on press of the button B, which doesn't exist in this. So this is how we have learned the state charts in academics, but let's try to write the same thing using code. And there are multiple ways to model this in the JavaScript code, but I'll start with something very similar, very familiar to us, which is the switch case statements. And remember the switch case statement is something, I would consider that as an abstract of if statements, because everything I can do in switch case statement, I can write it in basically if else if statements again. But we'll be using switch case statements. So what are state charts now? They are basically the extension of state machines, which gives us powerful features to introduce the concepts like inheritance. We call here it has a hierarchical states and there will be more powerful concepts like handling parallel states and setting up a next state using conditions which are called as guards and activities which are basically the actions that prolong till the end of the state. So these are the important concept when it comes to modeling it in real life applications. But we'll start with something very simple without any of the state charts and which is basically a state machine. So we refactor the entire previous code, the same handle input function, but with a switch case statement. We start with if the player state is standing and the input is B then jump or else if the input is pressed down, then basically duck. So this piece of code is a lot more easy. Now this is the same functionality as the previous one, but what's the real difference between the previous one and the current one? But before doing that, let's try to add one more feature of this, which is like shooting, which we thought of, we didn't do it in the last time code. And see if adding a new feature here, we'll actually break any of the previous code that we have written. So we already have the press B and press down while standing or code written previously. Now we'll add the shooting condition, saying on press of enter, the player should basically shoot. So I just add one more if condition and I'm done. I don't need to worry about did this break in the jumping state or ducking state, what about diving state? This is going to again break something else in the previous code that I have written? No, not at all. But the problems with this code is that shooting is something that gets done in all the states. So I have to keep repeating this same if else else if statement in all the jumping state and ducking state because shooting is something that you could be doing during the entire, any of the actions. So the problem code repetition and how do we reuse the code? This is where the state charts concept come, which is the hierarchical state, something that is repeating across all the states is hints us that we can model it as a hierarchical state. So demystifying state machines code, how is this a big deal than the previous if else statements? And it's basically a switch case statements that we have now and previously we have if else statements. So let's find out the differences. It's basically we have this almost same looking code, but some previously we have the input condition at the beginning of the function. And then we are doing something related to the state. And now we are reversing those statements. The simple difference is previously we are reacting to the events that we have and setting the next state. The current one takes into account the account of the current state and also the input and then sets the next state. What's the missing part is the current state. Great. State machines solve all our problems. So I was more like in this mood, trying to state machine all the code that I have seen or I have written in the past one or two months. And that is when I have realized that I could apply this to a dashboard. So I work at Grammar and we build a lot of dashboards. We end up building a lot of dashboards in the process of getting finding insights and then narrating them as stories. So one such dashboard is this. We have a multi-line chart and there were top filters and again, lot more parallel filters, tabs basically. And then there were few more filters. I mean, basically a lot of filters for exploring the data. So here we have a set of regions which are basically buttons. And every time a button is active, a line in the multi-line chart appears. So this is, this looks like a simple one, but the requirement will be is little tricky because we may end up with deselecting all the buttons in the right side and that will show an empty chart. And why would a user would want to ever see an empty chart? So what we say is whenever we are keep this, whenever we keep deselecting the buttons and we end up hitting the last active button, it shouldn't deselect itself and create an empty chart. It should basically select all the buttons that are there, thereby showing all the multi-lines. And in the same way, when we have all the buttons selected, we need to unclick off a particular button. Instead of deselecting it, it should basically select the only clicked button and the rest of the ones will be unselected. So this more or less looks like this. So I keep selecting all the buttons and, okay, I'm deselecting them and click on any button should only activate that. Yeah. So if I have to write the same thing in pure logic, is again, we can use a statement here. I just went with a switch case. So it'll look almost like this with the first condition saying if all buttons are active, activate the clicked button only or else. If the clicked button is the only active button, which is the last button, and I click on that button instead of deactivating it, activate all the buttons. And in the rest of the cases, just toggle the state of the button. So the first step in actually modeling a problem into a state chart or a state machine is to identify the states. And identifying states is something that we do not do when we write if-else statements. And this thing is actually the major advantage and the disadvantage of state machines. The advantage is that we get to do the upfront thinking, basically do something that we clearly avoid. Now we are introducing a design phase into the programming style. But that also means that we need to spend some time and writing a if-else statement would actually seem very convenient. But let's try to identify the states. There were multiple possibilities in identifying the states. We have almost six buttons here. I'm not considering the previous and planned buttons. So, and each button has a on state and an off state. So that makes it two power six states. And we want to avoid a state where all the buttons are deselected thereby avoiding a empty multi-line chart. So we can actually write this as a two power six minus one, 31 states. And create a finite state machine. Or we could create an abstraction over those 31 states and say that we only have three states. One is one button selected, the other is all buttons selected. The other is more than one button selected. Or the best is modeling the entire state chart as a one single state. So while during the process of identifying states try to optimize to reduce the number of states that will be modeling. So I'll good luck with trying with a 31 state programming switch case statement. I wouldn't be covering that up. I will be mostly covering on the three states which is I start with a starting state as all active buttons on click off that. There's only one state that it can go to which is make it only one button selected. And but when I'm in the one button selected if I click on the active button that is selected it basically goes to all active buttons. Or if I am selecting some other non active buttons I keep actually selecting them and I get to a state of one plus active buttons. And if I from one plus active buttons if I keep selecting more and more buttons I end up with all active buttons. That's a wrong thing. Or if I'm keep dissecting all the buttons I basically end up in a one button. So that's it. That's still a state chart. We are using guards here. How do we model this in the programming? We can use switch case statements. I would like to avoid that and use a better data structure basically a dictionary. And it's a mapping between the action I mean a state and a particular action and what the action should be. So the definition of action is the value. The action name which could be like a click event or a change event or trigger event any event. It could be a custom function custom event that you have created in your own front end JavaScript. So if you have to model the same thing what we do is the state name is all region selected on click of any button. We basically have this function that will define the side effects. Here the side effects is to select only one button which was actually clicked. So even dot target will give us the button that was clicked and we only make that button as active and that's for the buttons will be inactive. So all the side effects go into this. And in the same way we can keep doing the same thing repeated. And how do we actually run the entire state machine? We create a function called interpreter and every time a click event happens this interpreter function gets called and we take the current state into the state variable and dispatch an action which is basically calling the function that was in the value of the event. And transition the state to the new state. So if I'm in the all region selected I get transition to the one region selected and during the transitions if I want to trigger any events such as activating the previous and plan buttons that is where this piece of code will handle. And all of this will give us a time travel logger because I can get to on every input event I can get to see that okay I'm in this state and this is the event and this is the next state that I have gone to. So debugging this is very easy. So this is the one where we have added actually the DOM code that was required for it. But this is something that we have built by ourselves without using any library. And this does, this is a finance state mission because we do not have the hierarchy or concurrent states management system. And the most popular one these days is the X state which has, which is actually, which actually provides all the concurrent states handling or hierarchy activities, all these concepts bundled into the nicely interface library called X state. The documentation is really good and there are a ton of examples out there. The best thing that I have initially liked after writing this piece of code and started to use X state is here I have coupled the event and the behavior of the application which is basically the action tightly coupled. So what X state does is it simply goes in a declarative format and says that okay, list on all your states. So here I have a current state. I can have current state, I mean like state one, state two, state three. And on particular event of, on an event called input, you go to the next state. That's the simplest way to define. Here we haven't actually covered the syntax for the actions. So this is to introduce the library syntax. This is a simple example. What it basically does is it toggles a particular, let's say a button from green color to not green. And the event that we are triggering all the time is the change event. So if the initial state of the button is not green and a change event is triggered on that, it basically moves on to the green state. And from the green state, if a change event is occurred, so it goes on to the not green state, simple enough. And the structure is almost like current state on a particular event goes to the next state. And where do we handle the side effects? So it gives us a separate actions dictionary where we define set green as one action, where it adds a class called green to the particular button that was clicked. And remove green will basically remove the class from that button or the field in this case. So this is the current state which is not green on a particular change event. The target state is green and actions is something that happens during the transition of the states. And it will run the set green function that we have defined here. What this enables us again is to reuse the same action for multiple states. So if on moving from one particular state to the other state, there's a common action that needs to be executed. So this kind of interface will enable us that in a very nice way. So how do we model the previous three states solution to the X state library? In fact, this looks a lot more easier to understand because if I have the initial state as all region selected, which is the default state, and I do any click on any button, it basically sets the next state as the one region selected. And during the same transitioning of the state, this basically will trigger an action called deselect other than the clicked button. So that is one way of, so that's a three state model and that still is actually complicated more than using a particular if statement that we have seen in the beginning. So what's the best way to design this is to actually use a single state. And I have called the state as a default state because that's the only state it's actually will be in. And that is like non-zero selected button state. So I just avoided the long name. And so what happens is there's a simple state, default state, and there are three click even, I mean, and it's a self transitioning state on every click event. It basically transitions to the same state, but during the process, it'll actually evaluate a couple of conditions and execute a few actions. So this is a one to one modeling of our previous if a statement. So the one more reason why we don't model the entire user interfaces as state machines or state charts is modeling the simplest if statements is not very intuitive as much as we have something like if statements, but state charts with a state, it is solved very nicely. We still can do the same things. So all of us know that a state machine will be helpful when we have like 10, 15 states and five, six transitions. That's still a good use case for the state machines. But what if we want to actually model the entire application using a state machine? And it depends upon use case. I'm not recommending to do that. If you really are into building a product or a platform where your target customers or the non-technical audience who has to do drag and drop and design a custom and flexible application. In our case, we want to build a dashboard building application, but not at the cost of losing flexibility. So a domain consultant should be able to do it on their own. And we want if a particular custom feature is not available through the interface, the code generated from the interface should be hand-over to the developer. The developer adds the feature that is not added and gives back the same code. The code should be uploaded to the interface and the interface should still show the updated code and handle it. Most of the solutions out there only does it in the one way where the application user basically builds a graphical user interface. He models it in the GUI and exports the code. But once the code is exported, he can't again upload it back and actually rebuild on top of that. So this is where actually the XState comes because it's completely declarative. The declarative nature of this will enable us to create interfaces. So this is the same code which we are doing it in the single state. So we have couple of conditions and the target is always the default because it's a self-transitioning state. And the action is again the same actions we have actually put it in the actions tab which are defined at the bottom. The guards are the list of conditions that we are evaluating. Okay, so xvis is one of the state charts visualizer. So what it does is it takes the state chart that we have created and creates the, I mean, so if I copy paste my code from here, let me update this, this basically, okay, that doesn't refresh actually. So I can actually copy paste my entire state machine into this and click on the update and that will create the states here. And just basically on click of a particular event here which is a change event, it basically toggles between the not green state and the green state. In the similar way, we can take the entire code that we have here and paste it in the same thing, update. And now we see the default state which is a single only state and the rest of the ones are basically the guards conditions that will actually transition to the same state executing few side effects in between. So what are the pros of state machines? If you, I haven't actually sold the state machines concept as much as the outside front end community does because they actually picked a lot more complex examples. For me, I want to show that even a simple if statement can actually be modeled in state charts and that can actually be equally used for both simpler cases and the complex places. And a state chart is a very great communicator. If you are in an organization where you have to deal with multiple background people and most of them is like non-developer audience then you can actually, it's a common communication medium because it's basically a bunch of flow charts. You can actually communicate to a designer because the designer when designing an application things through flow charts. And what are the cons of this? So this might have looked, this might lead to a lot of lines of code but that was mostly because of the configuration. Even if it is more lines of code each line will probably be a couple of words. And the other important factor is the need for upfront thinking and modeling it. So what next, what can you do from, what are the takeaways from this talk or how can you actually you start using state charts whenever there's a particular use case that you are filling out. Statecharts.github.io introduces this concept of state charts very nicely. So this is one page that actually talks about what is a transition. So it shows the transitions in the particular state chart. In the same way, whenever I click on an action it shows the entry and exit. Okay, on entry transition, on exit transition. The actions are the turn light on, turn light off. There's a self transition. So spectrum.chart, chat is the place where all the state machine enthusiasts actually ask questions and get responses. And this is the link for x state library.