To handle the complexity of modern web applications, model-driven development comes to your rescue. This blog post will show you how to model your web application’s behavior with state machines and transform the latter into TypeScript code directly.
The generated code can easily be integrated with modern web development frameworks, like Angular or Ionic.
TypeScript is a free and open-source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript and adds optional typing to the language. TypeScript is designed for development of large web applications and compiles to JavaScript. As it is a superset of JavaScript, existing JavaScript programs are also valid TypeScript programs – that means you don’t need to go through a big rewrite to migrate them. TypeScript brings a lot of features you already know from other higher-level programming languages like Java. Some examples:
Some modern web frameworks like Angular 2+ or Ionic 2+ are based on TypeScript. These frameworks make use of the advantages of TypeScript when building scalable single-page web applications.
Since more logic is moved to the frontend, single-page web applications easily become complex. This is especially true for the interaction logic. This logic often ends op to be cluttered across the different parts of the application like event handlers, observables, etc.. In order to organize this better developers often end up in writing TypeScript classes that more or less implement state machines. At this point it is possible to go beyond typical implementation approaches and allow developers to model an application’s behavior graphically as a state machine and to transform it directly into TypeScript code using tools like YAKINDU Statechart Tools.
In this example, we will have a look at an application with a simple HMI (Human Machine Interface) that represents an infotainment system for cars.
This application consists of two screens:
The infotainment component represents a container for further components like infotainment menu, weather, music player and phone.
On the right-hand side of the image below you can see the menu with three items. If you click on an item, the corresponding feature will be displayed.
The demonstrated behavior is modelled with YAKINDU Statechart Tools as follows:
In the definition section we define a menuState variable of type string. The menuState is used to decide which state is to be entered.
Then we define an inevent onMenuChanged to respond to user interactions.
Finally, we define four operation callbacks which display the corresponding feature.
To configure the code generation process, YAKINDU Statechart Tools uses a textual generator model called SGen. It describes what should be generated where, and with which options. The generator model can be created either by using the provided YAKINDU Statechart Generator Model wizard or by creating a text file with the extension .sgen.
Using the Outlet feature, we specify that our target project is ycar_app.
The generated artifact should be placed into the src/app/gen/statemachine directory within the ycar_app project.
The generated state machine has some dependencies. They are generated into the library target folder src/app/gen/stateutils.
Using the GeneratorFeatures, we specify that our statechart should be created as an Angular service (useAngular = true) with an event-driven behavior (useEventQueue = true).
In context of Angular, the generated MenuService state machine was created as an Angular service. The state machine needs to be added as a provider to YMainScreenModule.
Next we have to customize the YMainScreenComponent to inject the service and write some glue code for setting the in events and the operation callbacks. We do that in the component lifecycle hook ngAfterViewInit:
From line 34 to 47 we define an operation callback object of type IOperationCallback. The members of this object are callback functions that are called from menuService.
In line 48 the menuOperationCallback object is passed as an argument to the setdefaultScopeOperationCallback function.
The mainScreenService.menuChanged observable is subscribed. Depending on the value of menuState, menuService.menuState will be set.
The demonstrated example is available in full in the example wizard of YAKINDU Statechart Tools. However, since the TypeScript generator is still in its beta testing phase, it does not come bundled with the YAKINDU Statechart Tools out of the box yet. Instead you have to install it manually. To do so, please go to Help → Install New Software and select YAKINDU Typescript Generator from our update site, as shown in the screenshot below.
Once you have installed the generator, you can import the project Web-based YCar App from our example wizard, which you can invoke using File → New → Example… → YAKINDU Statechart Examples.
Try it out and have some fun!
Web applications are becoming increasingly complex. To make the complexity manageable, it pays out to implement parts of an application in a model-driven way.
In this blog post I have described how to configure the generation process for our modelled state machine. I have shown how simple it is to integrate a generated TypeScript artifact, here: the state machine, to an existing Angular application. The only thing we still have to do, is to customize the Angular module and their component that uses the generated Angular service.
What’s coming next? Okay, it’s really cool to generate TypeScript code from a state machine, but what would you say if you could use existing TypeScript artifacts directly in a statechart, similar to our deep C integration – one of the main features of YAKINDU Statechart Tools? Yes, we are already working on that, and the development is well advanced. Stay tuned for more information about this!