Users of websites or applications expect the interface to instantly respond to their actions. A user presses the «Add to Cart» button, and immediately the product button changes to «In the Cart», and an item appears in the top menu next to a cart icon.
The reactive approach to development implies that the program itself monitors events and reacts to it. This is similar to working in Excel spreadsheets: the user changes the value of one cell. and all related cells automatically change their value.
In the article we will explain what the essence of reactive programming is, in which projects it’s necessary and in which unnecessary, and why we use NgRx — a library on the Angular framework — to develop reactive products.
We talk more about the framework and its capabilities in the article «Tasks we solve with Angular. Using as an example the POSiFLORA accounting system».
How a reactive site works
To make a user’s path from entering the site to paying for the order simple and convenient, you need to think through each of the user’s actions, and provide for automatic reactions to them. Any user action can be decomposed into stages:
- Event: A user action with the site interface. For example, a customer selects a product on the site and puts it into a shopping cart.
- Site request to the server: What product the buyer wants to put into the basket, and in what quantity.
- Server response: Information regarding a successful operation.
- Reaction: Changes made to the interface in response to a user action:
- The «Add to Cart» button on the product changes to «In Cart»
- Changing the icon of the cart itself
- The amount and quantity of the item in the cart are updated
The user only sees the text change on the button, while the program has already communicated with the server and confirmed the operation.
In order for the program to respond to user actions, the developer describes variables that contain data. In our example, the variable is the cart, and the data is its state: the type and quantity of goods.
When a request is executed to provide or update data, the site responds and provides the desired result: the contents and the icon of the basket, and the inscription on the button is updated.
With the traditional approach, developers need to register all actions manually: change the button, update the number and amount. This is handy for small projects. But if the program needs to process many streams of data from different sources, it’s difficult to think ahead and try to describe all reactions to all requests. A developer can make a mistake, forget to update a variable, or ignore a request.
A reactive approach implies that the program itself monitors events and reacts to them. The development process in this case looks like this:
- First, in the program, a developer defines:
- Reactive variable — Event source (Publisher). In our example, this is the state of the «Add to Cart» button.
- Dependent variables — Event subscribers. In the example, these are the cart icon, the quantity of goods, the cart amount, and the inscription on the button.
- When an event happens, a user clicks a button, and the state of the source changes. Subscribers receive this information and automatically change their state: cart type, number of items in the cart, amount, and the button text.
In reactive programming, subscribers watch the source change and automatically change their state. Thus, the reactive approach to programming allows you to process data in a stream: subscribers react to the event in parallel, not in turn. This is called «asynchrony»: while one long action is being performed, a second short one is already completed, and the result is available to the user.
Why we chose the NgRx library for reactive programming
NgRx is a library for reactive programming of applications in the Angular framework from Google. Libraries make development easier thanks to a set of ready-made solutions: functions, objects, and classes. OrbitSoft developers use NgRx in projects where it’s necessary to simplify and speed up the processing of data received by the server.
Here are the main reasons for using this library:
Fewer product errors
When working with large data arrays, there is always a risk of errors. Bugs lead to crashes in the program, and users certainly don’t like that. Reactive programming reduces the chance of errors. Static data is tied to the source of changes, and given a command to update it when an event happens: the different data results are updated automatically and independently from each other. Therefore, a reactive application or site runs faster, and crashes are reduced.
Additionally, the fundamental stack Angular — TypeScript, or strictly typed programming, helps to reduce the likelihood of errors. When a developer enters a variable, they immediately indicate its type. This is how the system understands what data the variable will work with. Later, this simplifies revision and changes to the code. Even a third-party developer will understand the purpose of assigning a variable, and won’t make mistakes.
Flexible data management
Example: a customer puts an item in the cart, but nothing happens, neither the amount nor the quantity of the item in the cart changes. The customer eagerly clicks the «Add to Cart» button a few more times.
In classical programming, the developer must take care that multiple clicks do not send a multiple «add to cart» signal to the server. They need to provide for the blocking of the button, or to not send a signal for multiple clicks.
In reactive programming, it’s possible to automatically interrupt the previous request and create a new one. Or, on the contrary, subscribers take data from the first event, and don’t react to the rest. A developer can provide different reactions to an event, and a library with many solutions allows them to be flexible.
Sorting received data
A source can send a lot of data. Not all of this data is needed by a particular subscriber. To remove unnecessary data and convert it into a format understandable to the subscriber, the data must be sorted, translated into the desired form, and given to the user.
For example, in CRM, the source sends sales data to subscribers: total sales, amounts per store, average check amount, number of transactions, etc. One subscriber is a window on the toolbar, which displays which store has the highest revenue today. This subscriber doesn’t need all of the sales information, only the maximum revenue for today, and the name of the outlet.
To sort the necessary information, data from the source is transferred to «pipes», tools that sequentially perform some kind of chain of actions. In our example, one pipe filters from all the data only the sales amounts for individual stores, a second sorts them and selects the largest one, and the third converts the data into a monetary format and gives it to the subscriber. The subscriber reacts: in the window on the CRM panel, the user sees the store with the maximum revenue and its volume.
Predictable code structure
Some libraries allow you to link the code in a way that is convenient for the developer. This isn’t always good. For other developers to also work with the program, parts of the code must be located in a predictable place. For example, the controller is after the model.
In the Angular framework, the developer writes code according to a given structure. This makes it easier to change, test, and debug the product. For the customer, this is also a plus: the product can be quickly implemented and start producing earnings.
Angular also has command line tools that allow you to create new components. For example, a commonly used component is the basic test description. It allows you to automatically prevent some errors in the code even before the product reaches the testers. So, if a new developer joins a large project, automated tests will help you to find and fix bugs even before the prerelease.
Ready-made components for interfaces
In Angular, you can add ready-made components from the material design system: banners, checkboxes, forms, buttons, and so forth. This helps in the creation of a modern interface, and simplifies the assembly and layout of the site. The designer doesn’t need to redraw components. He or she inserts ready-made ones into the layout, and adjusts them according to the customer’s brand book. The front-end developer adds a set of Angular material components to the project, and includes those that are needed for the layout on each of the pages.
We developed a reactive video portal using the NgRx library
We used the Angular reactive programming method for the video portal of a network of plastic surgery clinics. The customer conducts training sessions for doctors, and regularly uploads videos and files with training materials to the website.
The original video portal was rather outdated: it had become slow and was prone to errors. We optimized it. Now pages open instantly, large files are loaded completely, and the portal can withstand more than ten thousand simultaneous viewers during live broadcasts. Read more about this project in the article «OrbitSoft fixed it: how we redesigned a medical video portal from scratch». In this project, reactive programming was applied to all the data that we received from the backend.
We set up background file uploads
After optimizing the site, files began to upload in the background, and the client received notifications about the process. While a video is loading, users can continue browsing the site, and a pop-up window displays the progress of the download.
This became possible thanks to reactive programming: when a new file is loaded, the program divides it into parts, and loads them one by one. As soon as a new portion of the video is added, the assigned subscribers of the event (Subscribers) receive notifications and update information about the uploaded files.
We created a system of notifications regarding the start time and date of the broadcast
A few days before a live broadcast, an announcement is posted on the site. Users who want to watch it leave their phone number or e-mail. When the broadcast time approaches, they receive notifications. In this way, they don’t miss scheduled viewings or broadcasts.
To make this happen, the developer assigned an event — the start of the broadcast — and defined a subscriber — a message sending service. As soon as the administrator starts the broadcast, the subscriber sends notifications to users who filled in the contact details.
We optimized site search
Reactive programming made it possible to improve site search, responding faster to user requests.
When a user enters a phrase in the search bar of any section, they see preliminary results. If they select «View All», the site shows them a page with all of the results containing this phrase.
To make this work, the developer defined a subscriber and an event: entering text into the search bar. When a user enters a search phrase, the subscriber reacts to the event: it analyzes all pages of the site, and shows the result to the user. If the user reformulates or changes the request, the previous request is cancelled, the subscriber receives new data, and the process with the selection of suitable pages is repeated. In the classical approach, you would have to manually distribute data across pages.
Who is reactive programming in Angular not suitable for?
Reactive development is suitable for companies that need to process a large amount of data and distribute it across different parts of a project. For example, when a user clicks one button, and the table, graph, and other elements on the page are updated at the same time. In this case, the risk of developer error is high, and reactive programming reduces this likelihood.
In small projects, reactive development is redundant: there is no need to complicate the code if there are few processes.
For newbies in development
Due to the asynchrony of processes and automation, it’s not always clear to the developer from the outside where and how a task is performed. For example, the piece of subscriber code that responds to an event might be in one part of the code, and the source of the event in another. Therefore, it’s better if the project is supported by developers with experience in reactive programming.