What Is Reactive Programming (Best Tutorial 2019)

What Is Reactive Programming

What Is Reactive Programming

Have you ever heard about Reactive Programming or Reactive Systems? Do you think React.js is a reactive library? Have you ever thought about why you should use Rx.JS inside an Angular project?

 

Is Rx.JS the new Loadash? If at least one of these questions is often in your mind, this is exactly the right blog to find an answer!

 

In these pages you will have a chance to learn more about reactive programming and reactive architecture for front-end development: a programming paradigm that is becoming more popular, every day, in the front-end community; but these days it is probably one of the most misunderstood and abused paradigm.

 

The main goal of this blog is to provide a good understanding of what reactive programming is, how to use it in our projects, and particularly how to create fully reactive architectures for creating resilient and maintainable projects.

 

During this journey you will learn the following:

  • What Reactive Programming is and why it’s important
  • What are the best use cases of this programming paradigm
  • How to structure a fully Reactive architecture with different frameworks
  • What will be the future of Reactive Programming on the front-end ecosystem

 

If you are wondering if the concepts learned inside this blog are applicable also on a back-end architecture, my answer would be YES, or at least, the majority of them could be applied to your back-end architecture too.

 

Bear in mind that this blog will focus the attention on front-end architectures with JavaScript, but some of the concepts illustrated should be easily portable to other back-end programming languages such as Node.js, for instance.

 

This blog assumes that you already have a good understanding of JavaScript, in particular, ECMAScript 6 and 7 syntaxes; object-oriented programming; and possibly some knowledge of functional programming, but it’s not mandatory.

 

Let the journey begin! Every day when we open an editor or IDE to develop a program, we use our favorite programming language; sometimes we study a new one, but, consciously or unconsciously, we are making the decision of what kind of programming paradigm we are going to work with.

 

Reactive programming is not a new paradigm: it’s one of the buzzwords we are used to hearing about in the JavaScript community in the past year or so, and it will become more than just a buzzword in the future.

 

I don’t want to begin immediately by using too many technical terms because we will have enough time to learn about them while reading this blog, but it’s important that you understand what is the benefit of working in a “reactive way.”

 

If you read blog posts or articles on the Web, few of them are going to explain reactive programming with the spreadsheet cells example, where spreadsheet cells are reacting to changes happening in other cells after user input. This is definitely a good example but we can do better than this.

 

I’m sure you are familiar with the dependency injection pattern where an object is injected via the constructor or in a public method exposed by a class or module.

 

This pattern leverages several benefits like decoupling between two objects and the possibility of testing the hosting object in isolation without creating dependencies and so on.

 

In some programming languages when we use dependency injection we are going to define an interface as function’s argument in the hosting object and then we can interact with the methods available in the injected object.

 

The injected object, in this case, is used as an interactive object because the host knows exactly what the contract is and how to use it. In reactive programming instead, the hosting object will just subscribe to the injected one, and it will react to the propagation of changes during the application lifetime.

 

Looking at the image above, we can immediately grasp the main difference between the two approaches:

In the interactive example, object A is aware of which methods to call because knows exactly the B’s object contract, also if we have to understand who has affected the state of the ingested object, we will search across all the projects that we are interacting with.

 

In the reactive one, the contract is standard and object A is reacting to changes happened in object B, on top we are certain that any manipulation would occur inside the injected object; therefore we will have a stronger separation of concerns between objects.

 

Because the hosting object is reacting to any value propagated inside the object injected, our program will be up to date without the need for implementing any additional logic. It’s time for a simple example before we move ahead with other concepts. Let’s assume we have a class called Calculator with a method sum and a class

 

Receipt with a method print as shown in Listing 1-1.

 Check Snippet1.js
class Calculator { sum(a, b){
return a + b;
}
}
class Receipt { constructor(calculator){
this.calc = calculator;
}
print(itemA, itemB){
const total = this.calc.sum(itemA, itemB); console.log(`total receipt £${total}`);
}
}
const pizza = 6.00; const beer = 5.00;
const calc = new Calculator(); const receipt = new Receipt(calc);
receipt.print(pizza, beer);

 

As you can imagine, the program outputs “total receipt £11.”

What we are doing in this example is creating the Calculator object and a Receipt object, and then we inject the Calculator instance called calc and we call the method print from the receipt instance with few arguments.

 

Inside the print method, we are writing in the console the total price of the elements passed.

Checking the Receipt class implementation, you can spot in the print method that we are interacting with the method sum of the Calculator class and then getting the final result.

 

Now let’s try to implement the same example in a reactive way in Listing 1-2.

 

 Check Snippet2.js
class Calculator { constructor(itemA, itemB){
const obs = Rx.Observable.of(itemA, itemB);
const sum$ = obs.reduce((acc, item) => (acc + item));
return { observable: sum$
}
}
}
class Receipt { constructor(observable$){
observable$.subscribe(value => console.log(`total receipt: £${value}`))
}
}
const pizza = 6.00; const beer = 5.00;
const calc = new Calculator(pizza, beer); const receipt = new Receipt(calc.observable);

 

As you can see in this example, the Receipt class is subscribing to an object called observable, injected via the constructor, and all the logic of how to sum the prices and propagate them is delegated to the Calculator class.

 

Therefore, the Receipt class is just reacting to a change, happening in a certain moment of the program’s lifetime, displaying in the console the value emitted by the Calculator instance.

 

Another thing to highlight here is the contract between the objects: instead of knowing exactly what method we should call, we pass an, with a default contract, and we react when something changes inside it. 

 

Overall, it’s a very simple example but I hope it helps you to understand the shift of mindset we are going to have when we work with reactive programming; in the next few blogs, we will see more reactive examples like this one.

 

Programming Paradigms

Programming Paradigms

It’s time to spend some words on programming paradigms to shed some light on reactive concepts and comparing them with functional and imperative programming.

 

Imperative Programming

Imperative programming is probably one of the most well-known programming paradigms. Often, it’s the first paradigm that we learn for understanding how a computer elaborates a program: it gives us all the tools for defining implementation details in depth and specifying exactly how a program should behave step by step.

 

Let’s see an example of imperative programming:

class Calculator { constructor(){
this.VAT = 22;
}
sum(...items){ let total = 0; let i = 0;
for(i; i < items.length; i++){ total = total + items[i];
total = total + items[i] * this.VAT/100;
}
return total;
}
}
class Receipt { constructor(calculator){
this.calc = calculator;
}
print(...items){
let total = this.calc.sum(...items); console.log(`total receipt £${total.toFixed(2)}`);
}
}
const JEANS = 80.00; const SHIRT = 35.00; const SHOES = 90.00; const COAT = 140.00;
const HAT = 29.00;
const calc = new Calculator(); const receipt = new Receipt(calc);
receipt.print(JEANS, SHIRT, SHOES, COAT, HAT); //"total receipt £456.28"

Similar to the example discussed before, the sum method of the calculator object is accepting multiple arguments instead of just a couple, and we are summing all of them and applying the VAT value calculated per item.

 

As you can see, we are describing the exact implementation we want to perform: from defining a for the statement in order to iterate through the values in the array until expressing the VAT calculation for every single item.

 

Basically what we are doing is focusing on an implementation detail; potentially we could change the way we were iterating through the array’s elements and start from the last element in the array instead of the first one or use a different variable name from “i”; these are the levels of detail we usually handle with imperative programming.

 

Now it’s time to see how this example would be handled in functional and reactive programming.

 

Functional Programming

Functional Programming

Functional programming is getting more famous on a daily base. Many languages arise embracing this paradigm and many existing languages are embracing it too for the readability, maintainability, and testability improvements.

 

 If you are asking yourself why Functional Programming is becoming so popular, the answer can be found behind the concepts of this paradigm.

 

When we talk about Functional Programming we are talking about functions: in particular, we are talking about pure functions.

A pure function is a function that, given an argument, is always returning the same result; it’s predictable, easy to test, and doesn’t generate any side effect inside the program. Another important topic related to functional programming is the concept of immutability.

 

Immutability means that a specific value won’t ever change during its life cycle, but if we need to manipulate it, we will create a new instance that contains the manipulated version of the original object.

 

Even if you are not familiar with this concept or have never dealt with it, I want you to see at least one concrete example.

Usually, when you are dealing with an array and you want to iterate through the values and interact with them in an imperative programming way, you would write something like this:

const originalArray = [1, 4, 8, 12];

for(let i = 0; i < originalArray.length; i++){ originalArray[i] = originalArray[i] + 1;
}

console.log(originalArray) //[2, 5, 9,  13]

At this stage we have completely lost the initial values of the array called original Array; if we want to have a copy of the initial values, we would create a new array that contains the modified values and then we would check that one.

 

In functional programming, instead, we are working by default with immutable objects; therefore, every modification we need to apply won’t affect the original value but will generate a new one.

 

Taking into consideration the previous example, we could write in a functional programming way like this:

const originalArray = [1, 4, 8, 12];

const finalArray = originalArray.map(value => value+1); console.log(finalArray); //[2, 5, 9, 13]

 

As you can see from these simple examples, functional programming is focused on what you are trying to achieve more than its implementation details.

 

That’s a fundamental distinction compared to imperative programming. In fact, with functional programming we are describing our program, focusing on each action;

 

And we need to do describe the data flow of our program more than focusing on every single detail such as which variable we have to define for iterating an array or how to increment the variable inside the for the statement. Another important aspect of software programming is how to deal with state management.

 

In Object-Oriented Programming, we are used to encapsulating a state inside an object and changing it via different methods described in the same object. But in functional programming, we are trying to compose it via pure functions that accept as the argument a state and return a new state.

 

Redux (http://redux.js.org/), a very well-known library in the React community, aims to resolve the problem of state management by implementing a state machine pattern.

 

In Redux, when we want to change the application state, we will need to call a method that accepts two arguments: the previous application state and an action. And it is returning the new state without mutating the previous one.

 

An action is a simple object used for identifying in which state the application should transform. Relying upon pure functions will make our code more modular and more reusable, will create fewer bugs, and will suddenly become more testable!

 

Let’s try now to convert the previous imperative example, porting it to functional programming. See Listing 1-3.

Check Snippet3.js
class Calculator { getTotal(...items){
const total = items.map(::this.addVAT)
.reduce(this.sumElements);
return total;
}
addVAT(itemValue){
return itemValue + this.calculateVAT(itemValue);
}
calculateVAT(value){ const VAT = 22;
return value * VAT/100;
}
sumElements(accumulator, value){ return accumulator + value
}
}
class Receipt { print(total){
console.log(`total receipt £${total.toFixed(2)}`);
}
}

const JEANS = 80.00; const SHIRT = 35.00; const SHOES = 90.00; const COAT = 140.00;
const HAT = 29.00;
const calc = new Calculator(); const receipt = new Receipt();
receipt.print(calc.getTotal(JEANS, SHIRT, SHOES, COAT, HAT)); // "total receipt £456.28"

 

As we can see in the sum method implementation, we are focusing more on the actions we want to implement more than how to apply them; therefore, first we know that we need to calculate the VAT value for each single element (map method) and then to sum the items for retrieving the total (reduce method).

 

In this implementation we don’t need to specify how we are iterating through the array elements or specifying variables to keep the state of the iteration; we just focus on our goal.

 

Another thing to notice in this implementation is how we are using functions as an argument of other functions; this mechanism is called high-order functions and it is another cornerstone of Functional Programming.

 

Obviously, Functional Programming is not just that: it is a broad topic with many other patterns to take in consideration like currying, practical application, memorization, and so on, but this is not the main topic of the blog.

 

Bear in mind these concepts and possibly read a few posts online regarding them for mastering the different implementations because being familiar with Functional Programming will allow you to embrace Reactive Programming more easily.

 

If you are not used to thinking functionally, I strongly suggest peaking at a blog that describes this paradigm in your favorite language; it’s a great time investment, and you won’t regret it.

 

Reactive Programming

Reactive Programming

We have just briefly seen Imperative and Functional Programming, but then what about Reactive Programming?

Reactive Programming is not a new concept – it’s been a while since it has been used on server-side programming – but it’s becoming very popular on the front-end ecosystem also.

 

We have seen how to easily turn a quick example to Reactive Programming, but it’s not just that. With Reactive Programming, we could easily transform our code to Imperative Reactive Programming or Functional Reactive Programming.

 

The main concept behind this paradigm is the data flow and how an object observes and reacts to changes that happened during the life cycle of an application.

 

Let’s start defining what Reactive Programming means:

Reactive Programming is a paradigm based on asynchronous data streams that propagate changes during the application lifecycle.

What does it mean in practice? Let’s assume we have to develop a financial dashboard, and all the data are coming from a server that is aggregating them for client visualization.

 

For the client, we need to establish a polling mechanism or open a WebSocket communication for retrieving these pieces of information, and then we need to translate them into a nice user interface that will be consumed by our users.

 

Trying to decompose the challenge we want to implement and how we would be reasoning without Reactive Programming, consider the following:

1. We need to create a proxy, an action, or a command to retrieve the data from the server every few seconds, triggering the polling mechanism.

 

2. After retrieving the data, we need to analyze these data, possibly modifying or analyzing them to provide a friendlier visualization.

 

3. Then we pass these data to different components via a mediator, store, controller, or any other layer that is coupled with a view for updating it.

 

4. In the last part, we would be updating the DOM from the view, maybe highlighting only the data that have been changed since the previous change (in this case, a Virtual DOM mechanism could come to rescue minimizing the effort).

 

There a quite a few parts to take care and lots of events, commands, or signals to use in order to make these data flowing from different parts of our application to display them in our views.

 

What would you say if you knew there is a better way to do it? It’s a paradigm that will allow us to write less code and become more expressive and pluggable inside our current applications.

 

Obviously, I’m not saying we won’t implement all these tasks – Reactive Programming is not a silver bullet or a magic wand – but we will learn soon that this paradigm could have quite a few surprises in store regarding its simplicity and expressiveness. Another important concept of Reactive Programming is the way we are communicating within objects.

 

If you remember, a few paragraphs before, I showed an example of how we could solve a simple problem of communication between objects by injecting an observable instance instead of an instance of a specific class or module.

 

This could lead to many interesting scenarios that are currently not fully explored in the front-end panorama.

What would you say if the contract between objects become a standard one, and the instance we inject will have a predefined contract that will allow the hosting object to subscribe to changes from the injected instance?

 

This is not a new concept either: a similar idea was created in 1978 with Communicating Sequential Processes (CSP).

Despite the name, CSP allows you to work with sequential and parallel processes; a process is not more than a “channel” used for the asynchronous communication between objects.

 

In this way you are decoupling the objects using a channel for the communication; this channel though will allow you to not only pass data through it but to also do the following:

  • aggregating data
  • transforming data
  • reducing data
  • decorating data

 

On top of that, we will be able to manipulate channels (splitting, piping, merging, and so on) for creating sophisticated interactions between objects

 

CSP is a fine-grained implementation of what we are going to explore in the Reactive world. If you are interested in spending some time with CSP, I’d suggest checking the library called CSP-JS (ubolonton/js-csp).

Understanding how CSP works will speed up your learning process on Reactive Programming.

 

After this brief digression, we can move back to the main topic of this blog; it’s time now to see Reactive Programming in action in association with Imperative and Functional Programming.

 

Let’s start with the Imperative example shown in Listing 1-4.

 Check Snippet4.js
class Calculator { constructor(){
this.VAT = 22;
}
sum(items){

const items$ = Rx.Observable.from(items);
const total$ = items$.map(value => value + (value * this.VAT/100))
.reduce((acc, value) => acc + value);
return total$;
}
}

class Receipt { constructor(calculator){
this.calc = calculator;
}
print(...items){
const total$ = this.calc.sum(items);
total$.subscribe(total => console.log(`total receipt £${total. toFixed(2)}`));
}
}

const JEANS = 80.00; const SHIRT = 35.00; const SHOES = 90.00; const COAT = 140.00;
const HAT = 29.00;

const calc =  new  Calculator(); const receipt = new Receipt(calc);
receipt.print(JEANS, SHIRT, SHOES, COAT, HAT);

 

In this example, we didn’t change much compared to the imperative one, but let’s analyze what we have done:

In the print method of the Receipt object, we have transformed the arguments to an observable. We inject the observable to the sum method in the calculator class.

 

There we are first applying the VAT to every single element via the map method.

Then we sum these values and return another observable object. Last but not least, we subscribe to the observable object returned by the sum method, and we show the total price inside the console.

 

At this stage, I don’t want to go in too much depth with reactive terminology; but for now, think about an observable as an object that is wrapping the data and exposes some methods for manipulating the values – a sort of channel where data are flowing inside and we can apply a transformation to these data.

 

After understanding how to implement some reactivity to Imperative Programming, let’s see how the Functional example would look like, as shown in Listing 1-5.

Check Snippet5.js
class Calculator { getTotal(...items){
const items$ = Rx.Observable.from(items);
const total$ = items$.map(::this.addVAT)
.reduce(this.sumElements);
return total$;
}

addVAT(itemValue){
return itemValue + this.calculateVAT(itemValue);
}

calculateVAT(value){ const VAT = 22;
return value * VAT/100;
}

sumElements(accumulator, value){ return accumulator + value
}
}

 class Receipt { print(total$){
total$.subscribe(total => console.log(`total receipt £${total. toFixed(2)}`));
}
}

const JEANS = 80.00; const SHIRT = 35.00; const SHOES = 90.00; const COAT = 140.00;
const HAT = 29.00;

const calc = new Calculator(); const receipt = new Receipt();
receipt.print(calc.getTotal(JEANS, SHIRT, SHOES, COAT, HAT));

Also in this case, the example is pretty much the same but now the Receipt is using the observable called total$ that got a different signature from the previous example where we got just a simple number.

 

Once again, an observable allows subscribing to it and retrieving the values that are flowing inside it. At first glance these concepts could seem unimportant, but they will help us a lot when we try to create a full reactive architecture.

 

When Should You Use Reactive Programming

 Reactive Programming

Often, when a new trend is rising, a lot of developers are used to abusing the new technology or framework (hype-driven development). As we understood during this blog, Reactive Programming is used for handling the propagation of data during the life cycle of an application.

 

Therefore, a perfect fit for this paradigm would be a real-time data application like a financial dashboard or any monitoring system for instance. In a nutshell, we can say that any application that is heavily data-driven could be a great fit for Reactive Programming.

 

Obviously, it doesn’t mean you shouldn’t use this paradigm in other applications, but real-time web apps and applications with a large number of asynchronous transactions and mutations are where Reactive Programming really shines.

 

If we decide to use Reactive Programming inside existing architectures, such as Angular or Redux, for instance, it could be a good design decision because it could facilitate the update of our views or the state propagation inside components. 

 

Nowadays the Web is full of plenty of reactive examples, libraries and frameworks are raising them with great success, and embracing them will impose a shift of mindset in order to embrace the real power of this paradigm.

 

Another great benefit of Reactive Programming is the simplicity of testing your code and describing data flows in a concise but clear manner. Reactive Programming is already implemented in production environments of several large organizations such as Netflix, Google, and Microsoft.

 

Microsoft and Google, for instance, are a great contributor to the Reactive Programming movement (ReactiveX). Netflix, as well, is another company that is contributing heavily to the evolution of this paradigm with Rx.JS 5, and Reactive Programming is applied in several implementations currently in production.

 

How Should You Write an Application Fully Reactive

One night I went to a meetup in London where we were discussing the JavaScript trends for 2017. Funny enough, Reactive Programming was one of these trends and the facilitator asked a question to all of the attendees: “How many of you are working with Reactive Programming now?”

 

And half of the room raised their hands asserting a positive answer. After this question, the facilitator asked the following one: “How many of you are using React.js only as a Reactive library?” Then over 85% of the people that raised their hand at the previous question raised their hand again.

 

That wasn’t surprising for me because it provides an understanding of how few people are interpreting Reactive Programming in a correct way.

 

We could decide to structure our projects with a fully Reactive architecture where the communication/interaction between objects, the state management, and the interaction with endpoints are all handled in a Reactive paradigm.

 

Reactive Programming on the front end and back end brought up different architectures and implementations that are interesting to use but at the same time different from what we are used to dealing with.

In this blog, we are going to explore different approaches currently available inside the front-end Reactive community.

 

In this blog, we are going to explore the current status of front-end architectures. When we pick a framework for our projects, someone else made decisions for us on how to structure an architecture following best practices and design patterns for giving us the freedom to make design decisions, focusing mainly on what our applications should achieve more than how to structure them.

 

It’s important here to highlight the difference between architecture and design because often these terms are misunderstood.

When we talk about architectures, we are defining how our system is going to interact with different elements.

 

For example, think about the communication between a model and a view. Usually, when we define architecture we are defining the relationship between objects, how they communicate with each other, and so on.

 

Architectural decisions are hard to change because they usually drive a project in a specific direction, which would require a huge effort in moving it in a different direction. Design decisions, instead, are local decisions like choosing a specific library, algorithm, or design pattern for solving a problem in our project.

 

When we make a design decision on a project, it often doesn’t require a huge effort recovering from it, but in certain situations making poor design decisions will lead to a long refactoring of our system.

 

Let’s assume we need to solve a problem where every few minutes we need to refresh the data inside a specific view without refreshing the entire page but only the elements that need to change; we could decide to use React.js for its diff algorithm or create our own algorithm where we could have more control defining a diff algorithm close to our needs.

 

Sorting out the difference between architecture and design decisions, it’s time to see what we are going to explore in this blog. The front-end ecosystem is in continuous evolution, in particular in the past few years where we were experiencing different but fundamental changes that are improving the creation and maintainability of our projects.

 

We are probably living the most exciting decade of the past 10 years, overwhelmed by revolutionizing concepts that are often coming from the past but with a new twist, transforming them in useful ways and taking actual approaches for solving our daily challenges.

 

The front-end architectures changed a lot in the past 30 years, as we moved from the classic Model View Control (MVC) to more actual architectures that nowadays are present in many contemporary frameworks. 

 

This could be a representation in a timeline of this evolution. During this blog, we are going to see in action the most famous architecture and we are going to compare them.

 

The most important thing to remember is that these architectures are not obsoleted but that they are still valid concepts to use, and they can add a lot of value to our projects by drastically facilitating the development and maintenance of them.

 

Creating well-structured and flexible architectures also provide us the agility needed to embrace not only design changes but architectural ones as well.

 

Also, we need to bear in mind that these architectures can be converted to Reactive architectures if we apply the Reactive concepts in a proper way; therefore if our project is currently using one of them, we can still embrace the Reactive model, applying a few changes to enhance them and moving to a more reactive paradigm.

 

MV* Architectures

In this section, we are going to dig into the base concepts of MV* architectures; in order to do that we will work on a simple project (a basic calculator) for understanding how these architectures are composed, and how objects are communicating by embracing the SOLID principles that any project should take in consideration in order to be maintainable and extensible.

 

The three architectures we are going to explore in this section are MVC, MVP, and MVVM; let’s start with the oldest one, MVC!

S.O.L.I.D. soLiD is a set of principles created by uncle Bob. soLiD is an acronym that stands for:

  • s – the single-responsibility principle
  • o – open-closed principle
  • L – Loskop substitution principle
  • i – interface segregation principle
  • D – Dependency inversion principle

if you are interested in knowing more about them, i suggest watching this uncle Bob lecture: The S.O.L.I.D. Principles of OO and Agile Design - by Uncle Bob Martin

 

Bear in mind though, that all the code presented in this blog are just highlights of the final examples; therefore if you have a hard time following the snippets, feel free to download the blog examples first and switch from this blog to your favorite editor or IDE for consulting the code. Remember first to install all the dependencies with the command: npm install

And then you can run the n.p script called build in this way: npm run build

 

Model View Control

Model View Control

Model View Control (MVC) is an architectural pattern introduced in Smalltalk in the late 1980s by Trivet Reenskaug, and it is probably the most popular architecture of the past 30 years, used by millions of developers in any project independently of the language used. 

 

Its main characteristic is the separation of concerns and the single responsibility of its actors; the main innovation of this pattern was finally separating the data from their visual representation, a concept not fully explored until then.

 

In fact, the model objects are completely separated from their representation; therefore there isn’t any knowledge of the view inside the model. This detail becomes important when multiple views or controllers are accessing the same data because our model objects could be reused across different screens without any problem.

 

MVC is based on three basic principles:

  • Model: where the application state and domain data live
  • View: the user interface of our applications interacted on by the users
  • Controller: the glue between the model and the view, usually responsible for orchestrating the communication flow inside the application

 

How MVC Works

How MVC Works

Usually the controller instantiates the view and the model in the constructor or, in certain implementations, are injected by the main application class via dependency injection. The relation between a controller and the views could be one too many, so a controller could handle multiple views: the same relationship is valid for the models as well.

 

When we want to scale up this architecture for large projects usually we try to split up these relationships in order to have almost a 1 to 1 relation between these three objects so we can reuse components that are self-contained and architected in the same way the entire application works, like a Russian doll.

 

As described before the main aim of a model is storing the application state and everything that should be persistent across single or multiple views, usually every time the application state changes or data are updated; the model is triggering an event in order to update the view.

 

In the vast majority of implementations the object listening for any state or data change is the view, but in certain implementations, we can also find a total separation between the model and the view where the controller, in this case, is listening to the change and is propagating this information to the view.

 

The view is simply responsible for displaying the application data and listening for any user interactions.

 

This is the final result of what we want to achieve.

It is a simple calculator where every time we are clicking a button, we add the value on the display on the top and when the user is going to click the button “=” we will display the result.

 

Let’s start to explore our MVC example from the controller. See Listing.

 CalculatorController.js
initialize(){
const emitter = this.initEmitter(); this.model = this.initModel(emitter); this.initView(emitter, this.model);
}

 

In our implementation, the controller is going to instantiate the view and the model, and it’s injecting an event emitter for communicating between objects via events.

 

This will immediately improve the decoupling between objects because if in the future we want to reuse some of these objects in other projects, we won’t need to copy more than the object we are interested in, considering they are communicating via events, and as long as we respect the contract our code becomes reusable and flexible.

 

We are going to use React.js for handling the views of our project.

React usually renders the components again when there is a properties update, but in our case what we implement is using the event bus for notifying the view that a new result should be rendered on the calculator’s display, and then the view will retrieve the data from the model, updating with the new string the display.

 

In order to do that, we need to inject the model and the emitter instance inside the view. See Listing.

 

 CalculatorController.js
initView(emitter, model){
const cont = document.getElementById("app"); ReactDOM.render(<Calculator emitter={emitter} model={model} />, cont);
}

 

Then we will use the React Component life-cycle methods to store these two objects locally and listen for any change from the model; when a change happens, we are going to update a state property inside the React component to display the correct value. See Listing.

 

 Calculator.jsx
componentWillMount(){
this.model = this.props.model; this.emitter = this.props.emitter;
this.emitter.on("TotalChanged", _ => this.setState({displayValue: this.model.total}));
this.setState({displayValue: this.model.total})
}

 

So, every time the displayValue property is updated, this will trigger the render function; therefore the view will be updated with a new result as shown in Listing.

 Calculator.jsx
render(){
return(
<p>
<p style={displayStyle}>{this.state.displayValue}</p>
{this.createRow("row1", "AC")}
{this.createRow("row2", "7", "8", "9", "/")}
{this.createRow("row3", "4", "5", "6", "*")}
{this.createRow("row4", "1", "2", "3", "-")}
{this.createRow("row5", "0", ".", "=", "+")}
</p>
);
}

 

Inside the model instead, we are going to keep the application state, handling what should be displayed in our view and performing some calculations. Our model is composed of a few methods that will allow the controller to call every time a button is clicked from the Calculator keyboard as you can see in the following code in Listings.

 

 CalculatorController.js

initEmitter(){
let emitter = new LiteEventEmitter(); emitter.on("CalculateEvent", _ => {
this.model.calculate();
});
emitter.on("AddValueEvent", content => { this.model.addValue(content.value, content.type);
});
emitter.on("ResetEvent", _ => { this.model.reset();
})
return emitter;
}


Listing. CalculatorModel.js
calculate(){
this.totalOperation = math.eval(this.totalOperation); this.state = FIRST_OPERATION; this.emitter.emit("TotalChanged");
}
addValue(value, type){ if(type === NUMERIC){
this.totalOperation = this.getValue(value);
} else if(type === SYMBOL){
this.totalOperation = this.checkSymbol(value);
}
this.state = IN_PROGRESS_OPERATION; this.emitter.emit("TotalChanged");
}
reset(){
this.totalOperation = 0; this.state = FIRST_OPERATION; this.emitter.emit("TotalChanged");
}

 

The Controller, via the emitter object, is listening for any event triggered by the view and it is requesting to the model to perform some operations like reset, calculate, or add a new value. 

 

The model, instead, every time totalOperation value is changing it, notifies via the event bus our view that will display the new value updating the state property of our React component, triggering then the render function.

 

MVC is a pretty simple and straightforward pattern: there is a good separation of concern, each object has a unique responsibility, and all the information is well encapsulated.

 

Model View Presenter

Model View Presenter

Model View Presenter (MVP) is an architecture created in the 1990s, and one of its first appearances was made in IBM software. From my point of view, MVP shines when we need to reuse views or behaviors in different projects or different areas of the same application;

 

With this architecture, we start to give more importance to the modularization of our front-end applications and provide architecture specifically for a front end more than a generic one that could fit a back-end or front-end application like for MVC.

 

MVP is very helpful, in particular, when we work on cross-platform applications and we want to reuse the application data, communication layer, and behaviors or when we want to swap the views changing them at runtime or compile/transpile time. The main differences between MVP and MVC could be summarized in the following list:

 

Having a presenter instead of a controller, we will see in a moment which benefits come in with a presenter.

  • The relation between a view and a presenter is not 1 too many like in MVC but is always 1 to 1.
  • The best MVP implementation for having reusable components is when we design our views as passive views because swapping them becomes easier as long the contract between the presenter and the view is respected.

 

How MVP Works

The presenter object is inspired by the presentation model pattern, and my favorite implementation is when the presenter is designed as a Supervising Controller where it retrieves all the data useful for a view from the model, and at the same time, it should handle any user interaction updating the model.

 

As mentioned before, the views are passive or if you prefer dumb, they just know how the rendering logic works, possible animations, integration with CSS styles, and so on.

 

On top, the presenter is also dealing with updating the model and retrieving the information needed for rendering a view. Usually, in complex applications, you could have a persistent model (or more than one model may be exposed by a façade) across the entire lifecycle of an application and multiple presenters that retrieve and update the application data in the models.

 

Another important point to highlight is the fact that the model and the view should not be aware of each other; maintaining these two completely isolated from each other will help a lot in the case of large applications or when we need to swap views for targeting different devices.

 

Imagine for a moment that our assignment is a project where we need to target different devices like browsers, mobile, and smart TVs – exactly the same application but different UI for different targets considering that each target has different input methods and UI patterns.

 

With an MVP architecture, maintaining the behaviors inside the presenter, the business domain in the model and having just passive views for the UI will allow us to have similar behaviors across the application, reusing the same code for the models and changing the views – adapting them for the device we are targeting without much effort.

 

Passive View a passive view is a view without any knowledge of how the system works but just relying on another object for handling the communication with the system. a passive view doesn’t even update itself by retrieving data from the model;

 

This view is completely passive, and its main scope is focusing on what to render on the screen when a specific render function is called from a controller or presenter.

 

Supervising Controller a supervising controller is a specific type of controller that is handling user interaction as well as manipulating the view for updating it.

 

When a supervising controller is present in an architecture, the view needs only to redirect the user events to the supervising controller, and it will take care of handling the logic and updating the view with new data. the supervising controller is responsible for the communication in the system and it’s taking care to update the view it is associated with.

 

It’s time to see MVP in action with the Calculator example discussed above, but this time with the Model-View-Presenter in mind.

We can start from the App.js file wherein the constructor we are going to create the model and the presenter, and we import the view called Calculator.jsx.

 

We then inject React component and model inside the presenter as shown in Listing.

Listing. App.js
export default class App{ constructor(){
const mainModel = new CalculatorModel();
const mainPresenter = new CalculatorPresenter(); mainPresenter.init(mainModel, Calculator);
}
}
Then we can move inside the presenter where we are going to store all the objects
injected in variables and then we render the React component injected.

Listing. CalculatorPresenter.js
initialize(model, view){
this.model = model; this.view = view;
this.cont = document.getElementById("app"); this.renderView();
}
renderView(){
const component = React.createElement(this.view, {result: this. model.total, onBtnClicked: ::this.onBtnClicked}); ReactDOM.render(component, this.cont)
}

 

In our Presentation model, we are injecting the model and the view for having complete controls on them; we then call the method renderView that will be our trigger for communicating to a React component to render again because something happened inside the application and the UI should be updated.

 

As you can see, the view doesn’t have any knowledge of the model but we pass the result to display in our calculator via the props object exposed by React.

 

 Now it’s time to take a look at the view; and as we defined at the beginning of this section, the view should be a passive view, so in this case, it is taking care of what to render and how nothing else should be integrated in a passive view.

 

The communication with the presenter is happening via a method passed via the props object. Like we have seen in the renderView method, the presenter is passing a callback that should be invoked every time the user is selecting a button of our calculator.

Listing Calculator.jsx
import React from "react";
import ReactDOM from "react-dom";
import {ulStyle, acStyle, btnStyle, displayStyle} from "./Calculator.css";
export default class Calculator extends React.Component{ constructor(props){
super(props);
}
componentWillMount(){
this.btnClicked = this.props.onBtnClicked;
}
onButtonClicked(evt){ evt.preventDefault(); this.btnClicked(evt.target.innerHTML);
}
createRow(id, ...labels){
const items = labels.map((value, index) => { return <li key={`${id}_${index}`}
style={value === "AC"? acStyle : btnStyle} onClick={::this.onButtonClicked}>
{value}
</li>;
})
return(
<ul key={id} style={ulStyle}>
{items}
</ul>
)
}
render(){
return(
<p>
<p style={displayStyle}>{this.props.result}</p>
{this.createRow("row1", "AC")}
{this.createRow("row2", "7", "8", "9", "/")}
{this.createRow("row3", "4", "5", "6", "*")}
{this.createRow("row4", "1", "2", "3", "-")}
{this.createRow("row5", "0", ".", "=", "+")}
</p>
);
}
}

All the methods present in the React component are defined for rendering the correct button or the display, and this.props.onBtnClicked is the method passed by the presenter.

 

This method is identifying which button was selected so the presenter can capture the user interaction and it calls the correct method exposed inside the main model as you can see in the snippet below in Listing.

 

CalculatorPresenter.js
onBtnClicked(value){
switch (value) { case "AC":
this.model.reset(); break;


case "=":
this.model.calculate(value); break;
case "+":
case "-":
case "/":
case "*":
case ".":
this.model.addValue(value, SYMBOL); break;
default:
this.model.addValue(value, NUMERIC); break;
}
this.renderView();
}

It’s time to see what the model is doing; in this case, the model is taking care of all the calculations and maintaining the application state.

 

That will facilitate the debugging of our application because we know that the view is dealing merely with the UI of our application, and the presenter is handling the user interactions and the model keeps the application state and the caching of application data.

 

Let’s take a look to the model shown in Listing.

Listing. CalculatorModel.js
export default class CalculatorModel{ constructor(){
this.totalOperation = 0;
}
calculate(){
this.totalOperation = math.eval(this.totalOperation); this.state = FIRST_OPERATION;
}


addValue(value, type){ if(type === NUMERIC){
this.totalOperation = this.getValue(value);
} else if(type === SYMBOL){
this.totalOperation = this.checkSymbol(value);
}
this.state = IN_PROGRESS_OPERATION;
}
checkSymbol(value){
const str = this.totalOperation;
if(this.state === FIRST_OPERATION){ return str + value;
}
return !isNaN(str.charAt(str.length - 1)) ? str + value : str. substr(0, str.length - 1) + value
}
getValue(value){
return (this.totalOperation == 0 || this.state === FIRST_OPERATION)
? value : this.totalOperation + value;
}
reset(){
this.totalOperation = 0; this.state = FIRST_OPERATION;
}
get total(){
return this.totalOperation;
}
}

As you can see in the model, there are all the methods called by the presenter, like reset or calculate, and a few others like check symbol and getValue, used for handling the application logic. 

 

The separation of concerns in MVP is very strong and any application would be easier to debug and maintain if we properly apply these few concepts; it’s definitely an architecture that largely improved the MVC concept created 10 years before it.

 

Model View View-Model

Model View View-Model

Model View View-Model (MVVM) is an architecture created by Microsoft in 2005 for handling the GUI management with Windows Presentation Foundation (WPF). It sticks with a true separation between the view and the model like we have seen in the MVP architecture, but MVVM encapsulates few differences compared to other architecture.

 

How MVVM Works

The first difference is that we have a View-Model instead of a presenter; this specific object will be the bridge between the data stored inside a model and the view.

 

In a nutshell, the view-model is responsible for exposing the data present inside the model to the view and it is also responsible for preparing the data in a way that the view expects, so you can immediately understand that the logic of the view-model is tightly coupled with what the view should render.

 

For instance, let’s imagine that we have a stock value stored in the model with dollars currency but the view needs it to be shown in euro. In MVVM the model stores the raw data, that is, dollars value and the view-model would be responsible for converting the value to a given currency, in this case, euro.

 

Another important aspect of the View-Model is the fact that it has a relationship with the views that is 1 too many: therefore we can have one view-model that is handling multiple views or components.

 

The communication of the View-Model and the view usually happen via bindings; therefore every time a value is updated on the view or in the View-Model, this value is communicated to the other object in order to keep it in sync.

 

It’s very important to understand that with MVP we enforced the concept of complete separation between the model and the view and in MVVM this strong concept doesn’t change at all.

 

The model is very simplistic; we store data in a raw format without any particular change, and in this case, we should even avoid keeping the state in the model and moving this information to the view-model or even the view if it’s a small component.

 

Let’s see now how our calculator would work with an MVVM architecture.

The App.js file is instantiating all the objects for an MVVM architecture: model, view- model, and view; in the view-model constructor we are going to inject the model and view instances so it will be able to retrieve data from the model and serve the view with the correct value to display. 

Listing. App.js
export default class App{ constructor(){
const model = new CalculatorModel(); const emitter = new LiteEventEmitter();
const vm = new CalculatorViewModel(model, emitter);
const cont = document.getElementById("app"); ReactDOM.render(<Calculator emitter={emitter} initValue={model.total} />, cont);
}
}

 

The Calculator view is a React component that has two key concepts: dispatching the data from the view to the view-model and retrieving the data from the view-model.

 

In order to do that we can use a data binding library or simply events as both are accepted from MVVM architecture, therefore we are using an event emitter, injected when the view and the view-model were instantiated, for handling the communication between these two objects, as shown in Listing.

 

Listing. Calculator.jsx
componentWillMount(){
this.setState({displayValue: this.props.initValue}) this.emitter = this.props.emitter; this.emitter.on("UpdateDisplayValue", value => this.setState ({displayValue: value}));
}
manageDisplayState(value){
switch (value) { case "AC":
this.emitter.emit("ResetEvent") break;
case "=":
this.emitter.emit("CalculateEvent") break;
case "+":
case "-":
case "/":
case "*":
case ".":
this.emitter.emit("AddValueEvent", {value: value, type: SYMBOL})
break; default:
this.emitter.emit("AddValueEvent", {value: value, type: NUMERIC})
break;
}
}

In manageDisplayState we have all the events we will communicate to the view- model, but in the componentWillMount, we define only the event we need to listen for updating the calculator’s display.

 

The rest of the view is very similar to the other views we have discussed in the previous examples.

 

Now it’s the turn of our view-model. Here we need to do exactly the opposite of how we handled the events in the view; therefore we are going to listen for all the events emitted by the view and dispatch the event for updating the view’s display every time the value changes. 

 

Listing. CalculatorViewModel.js
initialize(){
this.emitter.on("CalculateEvent", _ => { this.calculate()
});
this.emitter.on("AddValueEvent", content => { this.addValue(content.value, content.type);
});
this.emitter.on("ResetEvent", _ => { this.reset();
})
}
updateDisplayAndState(state){ this.state = state;
this.emitter.emit("UpdateDisplayValue", this.model.total);
}

 

The view-model is responsible for retrieving and updating the data stored in the model, so every time the user clicks a button in our view we are going to update the value in the model and then call the updateDisplayAndState method for dispatching this change to the view.

 

We keep a state internal to the view-model to understand which method we need to call during the calculation; therefore we need to update it when the state is changed.

 

Let’s see, for instance, how we handle the changes in the three methods we have created for handling these operations, as shown in Listing.

 

Listing. CalculatorViewModel.js
addValue(value, type){
let valueToAdd; if(type === NUMERIC){
valueToAdd = this.getValue(value);
} else if(type === SYMBOL){
valueToAdd = this.checkSymbol(value);
}
this.model.add(valueToAdd) this.updateDisplayAndState(IN_PROGRESS_OPERATION)
}
reset(){
this.model.reset(); this.updateDisplayAndState(FIRST_OPERATION)
}
calculate(value){
this.model.calculate(value); this.updateDisplayAndState(FIRST_OPERATION)
}

All of them are doing two main operations:

1. They are updating the model.

2. They are dispatching to the view the new value to display.

 

It’s now clear that the majority of application business logic is present in the view- model; therefore if we want to reuse a specific component or part of the application. we need to maintain the event or the binding contract between the view and the view- model as it is.

 

So we can say that these two objects become slightly more tightly coupled compared to their relation in the MVP architecture.

 

Last but not least, it’s time to discuss the model. As you can see, the model just exposes a few methods in order to update the value to display;

 

it doesn’t have any data manipulation or any state, and in this case, the model is just a data representation of the main application so if we need to use it in combination with another view-model, the model will provide the data expected and nothing more. See Listing.

Listing. CalculatorModel.js
export default class CalculatorModel{ constructor(){
this.totalOperation = 0;
}
calculate(operation){
this.totalOperation = math.eval(this.totalOperation);
}
add(value){
this.totalOperation = value;
}
reset(){
this.totalOperation = 0;
}
get total(){
return this.totalOperation;
}
}

 

JavaScript Frameworks

JavaScript Frameworks

Now that we have explored the basics of MV* architectures, understanding the benefits and the issues related to each of them, it’s time to review what the JavaScript ecosystem is proposing and how these architectures are implemented.

 

I’m sure you will realize very soon that understanding the three architectures mentioned before will help you to capture the technical approaches provided by well-known frameworks like Angular, Ember, or Redux.

 

In this section we are going to re-create our calculator application three more times: the first one with Angular, then with Ember, and we will conclude this journey with the combination of React and Redux.

 

Angular

Angular

Angular is an open source framework created and maintained by Google. It’s been around since 2010 and has reached recently version 5, but from now on Google explained that we should just call it Angular.

 

This framework passed through different stages in the past years, from a huge hype when launched with version 1; then, after the announcement of version 2 not being retro-compatible with the previous version, many developers decided to move away from it and embrace other frameworks – in particular, React and Flux or Redux or similar combinations.

 

Recently, as in 2017, Google released a new version that should enhance the experience of the JavaScript developers with Angular, providing a complete ecosystem of tools and patterns in order to work easily with this framework without the need to scrap the Web for assembling multiple libraries inside the same project.

 

Since version 2, Angular embraces TypeScript as its main language; JavaScript ES6 and Dart are supported too, but the vast majority of the resources in the Angular website are prepared with TypeScript.

Angular as a framework is providing a full architecture and utilities out of the box with also an interesting CLI tool for speeding up a developer’s productivity.

 

TypeScript is a typed superset of Javascript, and it enhances the language adding enum, Generics, abstract, and interfaces very familiar with strictly typed languages like Java, for instance. more information on the official website: https://www.typescriptlang.org

 

How Angular Works

The architecture we will evaluate in this section is related to Angular 2 and onward, so we won’t take into consideration the previous one because it works in a different manner.

 

Angular architecture introduces four interesting concepts:

  • Dependency Injection
  • Modularity with NgModules and Components
  • Data binding between Templates and the Components
  • Large use of decorators for defining the objects like Components or Modules

We will now go more in depth of this architecture, analyzing the different parts that compose an Angular project.

 

Any Angular application has at least a NgModule called the root module; a module is not like a normal JavaScript Module. The peculiarity of the NgModule is the metadata;

 

In each NgModule (root module included), we will describe how the module is composed, and in particular, we will define which components belong to a module, if a module has dependencies from other modules, directives, or components; and we also describe the services used by the components present in the module.

 

As described before, any Angular application contains at least one module called the root module. For instance, this is the root module created for our Calculator project in Angular:

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';
import { AppComponent } from './app.component'; @NgModule({
declarations: [
AppComponent
],
imports: [ BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

As you can see in this code snippet, Angular is largely made up of decorators (@NgModule) for wrapping our code inside the Angular framework.

 

Decorators the decorators in Javascript are actually in the proposal (stage 2) for becoming part of the language (more information on the proposal at this link: tc39/proposal-decorators). they are based on a simple concept: a decorator wraps a function, augmenting its functionalities without manipulating the function decorated.

 

Usually, in a decorator, we add methods or properties that should be common in our project at runtime; that’s why angular is using a large number of them. it’s so we can write our logic without inheriting from some base class, thereby creating a tightly coupled connection between and decorating it with the built-in functionalities available in the framework.

 

The next topic to introduce is the Angular components. Since Angular 2 we have the possibility to create components, and we can think of them as a bridge between the template system present in Angular and the data we can retrieve from REST API or specific endpoints.

 

Their role is mainly retrieving the data and populating the template with new data via a binding system that is present out of the box in Angular 2.

 

The Angular component is a mix of properties we can find in the presenter and the view-model. In fact, the following is true:

  • A component is updating the view via binding like in the view-model object.
  • The relation between a component and a template is always 1 to 1 like for the presenter.
  • The component handles all the user interaction happening in the template like for the presenter.

 

In order to define a component in Angular, we need to specify another decorator, @Component. For our calculator example, we have defined just one component considering how simple the application is; but potentially we could have split them in multiple parts as shown in List.

Listing. App.component.ts
const ON_SCREEN_KEYBOARD = [ ['7', '8', '9', '/'],
['4', '5', '6', '*'],
['1', '2', '3', '-'],
['0', '.', '=', '+']
];
@Component({
selector: 'app-root',
templateUrl: './app.component.html', styleUrls: ['./app.component.css'],
providers: [UpdateTotalService, CalculatorModel]
})
export class AppComponent implements OnInit { onScreenKeyboard = ON_SCREEN_KEYBOARD; total:string;


constructor(private updateTotalService:UpdateTotalService){}
ngOnInit(): void {
this.total = this.updateTotalService.reset();
}
updateTotal(value: string){ switch (value) {
case 'AC':
this.total = this.updateTotalService.reset(); break;
case '=':
this.total = this.updateTotalService.calculate(); break;
case '+':
case '-':
case '/':
case '*':
case '.':
this.total = this.updateTotalService.addSymbol(value); break;
default:
this.total = this.updateTotalService.addValue(value); break;
}
}
}

 

As you can see in the decorator (@Component) we are specifying the HTML template and the CSS associated with the component. The objects to inject will be accessible inside the component but they will be instantiated by Angular and a selector that is just an ID to identify the component.

 

The last thing to mention about Angular components is that we can use life-cycle hooks like the ngOnInit method that is triggered when the component is initialized and in our case we use it to set the first value in our calculator display.

 

Now it’s time to see how the components interact with templates. Angular has its own way to handle HTML markup; we can use some directives in order to iterate through a data structure for displaying multiple HTML elements or for adding specific attributes if a certain condition happens in our code.

 

Directives in angular are instructions for the HTML template on how the template should handle the Dom. In our example, we have associated an app.component.html template to the app.component.ts described above and this is the code used for the template:

<p class="displayStyle">{{total}}</p>
<p class="acStyle" (click)="updateTotal('AC')">AC</p>
<ul *ngFor="let row of onScreenKeyboard">
<li *ngFor="let value of row" class="btnStyle" (click)="updateTotal(value)">
{{value}}
</li>
</ul>

 

In this code, it is important to highlight a few concepts. The first concept is that the binding with the total property is created inside the component, so every time we are updating this value, the new value will automatically be displayed inside our template.

 

The other interesting thing is how we have created the buttons in our calculator; we are iterating an array present in the component object and with *ngFor directive we are creating multiple tags with different values;

 

when a user clicks on the button we are calling the method updateTotal passing the button’s label; also in this case we use Angular markup for triggering the user interaction ((click)="updateTotal(value)").

 

Interestingly enough, just with few lines of code. Angular provides a simple but very powerful mechanism of data binding, templating, and styling our views.

It’s time to talk about the dependency injection part; as we saw in the component decorator we are defining an array of providers. Basically we are injecting UpdateTotalService and CalculatorModel to the component.

 

The CalculatorModel won’t be used by the component but if we want to inject this object inside the service, we need to specify it there.

 

What is a Service in Angular? A Service is inspired to the Command Pattern, and it’s used for fetching data from an endpoint or for retrieving/passing data to a model like in our case.

 

Command Pattern the command pattern is a behavioral pattern. a command contains all the objects needed to perform an action when a specific event happens inside an application such as user interaction, data fetching, and so on.

 

usually, the command pattern has an interface with just one public method called execute; and after instantiation, where we can inject the objects needed for performing the action, we can call this method for performing the logic described inside the command. 

 

usually, the command is used for decoupling the interaction within objects like the controller and model or presenter and model, and then we maintain them totally decoupled.

 

This is our UpdateTotalService class as shown in Listing.

Listing. UpdateTotalService.ts
@Injectable()
export class UpdateTotalService{ constructor(private model:CalculatorModel){}
calculate(){
this.model.calculate(); return this.model.total;
}
addValue(value){ this.model.add(value, VALUE); return this.model.total;
}


addSymbol(value){ this.model.add(value, SYMBOL); return this.model.total;
}
reset(){
this.model.reset(); return this.model.total;
}
}

This service exposes a few methods that will be used for manipulating the model in a specific way.

The model is injected in the constructor via the framework; therefore when we call this.updateTotalService.reset(); from the component class we won’t need to have any knowledge of the model but the service will return the value retrieved from the model, isolating the view from the model like we have seen in the MVVM pattern, for instance.

 

Another important thing to notice in this class is the injectable decorator provided by Angular for describing a class that is injected inside a component; just adding this decorator, the framework knows when to instantiate and inject.

 

The last part to describe is our model that is a very basic model with some knowledge on how to manipulate the data to store. Here again we are using the @injectable decorator for the possibility of being injected by Angular. See Listing.

Listing. CalculatorModel.ts
@Injectable()
export class CalculatorModel{ private state:string;
private totalOperation:string;
constructor(){
this.state = FIRST_OPERATION; this.totalOperation = '0';
}
get total(){
return this.totalOperation;


}
reset(){
this.totalOperation = '0'; this.state = FIRST_OPERATION;
}
add(value, type){ if(type === VALUE){
this.totalOperation = this.getValue(value);
} else {
this.totalOperation = this.checkSymbol(value);
}
this.state = IN_PROGRESS_OPERATION;
}
calculate(){
this.totalOperation = math.eval(this.totalOperation); this.state = FIRST_OPERATION;
}
checkSymbol(value){
const str = this.totalOperation;
if(this.state === FIRST_OPERATION){ return str + value;
}
return !isNaN(Number(str.charAt(str.length - 1))) ? str + value : str.substr(0, str.length - 1) + value
}
getValue(value){
return (this.totalOperation === '0' || this.state === FIRST_ OPERATION) ? value : this.totalOperation + value;
}
}

 

Our model is a simple object that contains the source of truth for our application, maintaining the state and the value that should be displayed inside the views.

 

Just to summarize the Angular calculator example: we have seen the key concepts of Angular, we also noticed quite a few similarities with MVVM and MVP architectures like the relationship between view and template or who is handling the user interactions.

 

The last thing worth mentioning is that Angular can become a reactive architecture pretty easily because it incorporates Rx.js library inside the framework; therefore, within a certain degree, we can twist this architecture to a Reactive one almost out of the box.

 

Ember

Ember

Ember is a framework oriented to web applications. It’s well-known in the JavaScript community and used by large organizations such as Netflix or Groupon.

 

Ember has an interesting ecosystem composed by EmberCLI, EmberData, and Ember as a JavaScript framework.

The paradigm behind Ember is slightly different from other frameworks but the productivity is high if the application fits this paradigm. Ember favors convention over configuration;

 

A key thing to remember is embracing the member CLI tool because it will facilitate your life and boost your productivity, the CLI takes care to generate all the files needed for a specific view (template, router, unit testing files, and so on), model, route, or even controller.

 

The Ember framework shines when a project has an architecture “fat server – thin client” where the majority of the logic is handled on the server; the client should be as dumb as possible and it should be a multipage application over a single page application (SPA).

 

How Ember Works

Ember architecture is based upon MVVM architecture, and there are some key elements that composed this framework:

  • Routes
  • Templates
  • Components
  • Controllers
  • Models

 

In Ember, everything starts from a routeing module and each view is tightly coupled with the endpoint associated. By default any Ember application has a main route system where we define all the application routes; for instance, in our calculator application, we have defined this route shown in Listing.

Listing. Router.js

Router.map(function() { this.route('calculator', {path: "/"});

});

 

That means the root of our web application will be routed to the calculator route. Because Ember works with conventions, we need to save the modules in the right folders in order to be picked up. But luckily the Ember CLI comes to the rescue by providing some useful commands that prepare all the files needed out of the box:

 

Ember generate route <name>

And automatically the CLI will generate a route file, the associated text file, and the template, and then it will also insert the code for the new route to the application route system.

 

The route we created for our calculator exposes the model to the template; in Ember, only the routes and the controllers have access to the model. Therefore, there is a strong separation of concerns between the view and how the model should be in an MVVM architecture.

export default Ember.Route.extend({ model(){
this.store.push({ data:[{
id: 1,
type: "calculator", attributes: {
total: "0",
state: AppState.FIRST_OPERATION
}]
});
},
relationships: {}
}
});
return this.store.peekRecord('calculator', 1);

 

The concept of Model in Ember is slightly different from what we are used to; the Model class defines that the value will be present in the store (the concrete model) facilitating the data validation when they hit the client side of our Ember application.

If we check our model class, present inside the model's folder, we can see that we are defining two properties” both of type string, one called total and the other state. See Listing .

 

Listing. models/calculator.js import DS from 'ember-data'; export default DS.Model.extend({
total: DS.attr("string"), state: DS.attr("string")
});

As you can see from the route code above, the store is a data structure centralized for the entire application (think of it as a Singleton), accessible by the routes and controllers, so independently from the number of templates, routers, or controllers our application is composed of, we have a unique source of truth to fetch or cache data.

 

The store object is a very interesting one because it allows data to be automated and fetched from an endpoint, and then it will store the response directly inside the store object without handling all the code for defining these kinds of operations.

 

The store works with records; a record is a concrete model that contains the data fetched from a REST endpoint or cached inside the application like in our case.

 

It’s very important to notice the structure of an object stored in a record, as shown in Listing.

Listing. routes/calculator.js
{

id: 1,


type: "calculator", attributes: {
total: "0",
state: AppState.FIRST_OPERATION

},
relationships: {}
}

 

Inside the store we need to define the data object with a unique ID; a type value, used for retrieving it later on; and the attributes we need to store inside it, for our application will be the value total and the application state.

 

Because we are not fetching the data from any remote endpoint we are using peek Record method, which will skip the server request and retrieve the data directly from the concrete model.

 

Instead, if we would need to retrieve data from a specific REST endpoint, we could use find Record that will perform a request to the endpoint specified, and it will store the response inside the store object.

 

Our application logic sits in the controller where we are providing public methods for the views to be called and we are handling the setting and getting of data to and from the model.

 

When we extend the base controller from the Ember framework we have an object called actions where we can expose all the methods to the template; in our case, we just have one method called updateTotal:

export default Ember.Controller.extend({ onScreenKeyboard: [
["7", "8", "9", "/"],
["4", "5", "6", "*"],
["1", "2", "3", "-"],
["0", ".", "=", "+"]
],

actions:{
updateTotal(value){ let result;
let model = this.store.peekRecord('calculator', 1);
switch (value) { case "AC":
model.set("total", 0);
model.set("state", AppState.FIRST_OPERATION); break;
case "=":
result = math.eval(model.get("total")); model.set("total", result); model.set("state", AppState.FIRST_OPERATION); break;
case "+":
case "-":
case "/":
case "*":
case ".":
result = checkSymbol(model.get("total"), value, model. get("state"));
model.set("total", result); model.set("state", AppState.CALCULATING); break;
 }
});

default:
result = getValue(model.get("total"), value, model. get("state"));
model.set("total", result); model.set("state", AppState.CALCULATING); break;
}
}

 

Here in each case we are retrieving the current value from the store and manipulating it, but the annoying part is that Ember works a lot with strings in order to identify a specific object or value.

 

Therefore we won’t have code completion provided by our editor and it could be prone to error if it’s not properly wrapped in a constant statement

 

The last bit to discuss is the template. Ember is using handlebars out of the box; therefore if we are familiar with this famous template library we will be productive in no time.

 

Handlebars have some specific markup, like Angular, for identifying specific behaviors like filtering, creating similar tags populated with data retrieved from the controller or the route and so on.

 

This is the handlebars code needed in order to render our calculator:

<p class="displayStyle">{{model.total}}</p>
<p class="acStyle" {{action "updateTotal" 'AC' on="mouseDown"}}>AC</p>
{{#each onScreenKeyboard as |row|}}
<ul>
{{#each row as |value|}}
<li class="btnStyle" {{action "updateTotal" value on="mouseDown"}}>{{value}}</li>
{{/each}}
</ul>
{{/each}}

 

It’s interesting to highlight how we handle the method exposed by the controller via the action command:

{{action "updateTotal" value on="mouseDown"}}

We identify the method name passing a parameter called value in this case, and specifying when the method should be invoked: in this case on mouse down.

 

To summarize, Ember is a really productive framework based on MVVM architecture with a lot of common activities ready to be used out of the box. It favors convention over configuration, it has a reach ecosystem composed of different tools and libraries, and the documentation is really exhaustive.

 

React + Redux

React and Redux is a combination of libraries that together can resemble a minimal framework with a large ecosystem that is not imposed at the beginning like for Ember or Angular but is more oriented to a plug-in system where we can use what we really need without the need to import everything up front.

 

React is a library useful for manipulating the DOM, based on components as the first citizen; it takes care of the view part of an architecture only, implementing a smart algorithm like the reconciliation one – a diff algorithm used for rendering only the part of the DOM that should change.

 

React introduced a very powerful concept embraced nowadays by several other libraries: the Virtual DOM. The Virtual DOM is a DOM representation where the diffing algorithm operates at first glance and where React understands what should change and when minimizing the changes to the real DOM and improving the performances of our web applications.

 

Reconciliation is a key concept for react. if you want to know more, i suggest reading the official documentation regarding this topic: Reconciliation | React

On the other hand, Redux is a state container not tightly coupled with React because we can find examples of Redux used in combination with other frameworks like Angular.

 

Redux is solving a well-known problem of how to manage the state inside an application.

The most interesting part of it is that it leverages a concept introduced in 2015 from another library called Flux, created by Facebook, of unidirectional flow.

 

Unidirectional flow is a powerful but simple concept: the objects communication inside an application should be unidirectional, and this, in combination with good encapsulation, will allow any application to be easier to debug, to be picked by any team because also complex applications are easy to understand and debug, thereby improving the code quality and the possibility of extending them.

 

The Redux paradigm is straightforward and is composed of only three key elements:

  • Actions
  • Reducers
  • Stores

The action is just a plain JavaScript object containing the information of what happened inside the application.

The reducer is retrieving from an action that the interaction happened in the application and knows how the state should change based on the action dispatched.

 

Finally, the store is the object that brings all together; the store is passing to the reducer the current state tree and the action, and it waits until the reducer provides back the new state, then the store will append to the state tree and all the objects that are listening for a change will be notified.

 

Redux was created on top of three core concepts

Single source of truth: the application state is represented inside a tree defined inside a single object called the store.

 

The state is read-only: the only way to change the state with Redux is via an action.

Changes are made with pure functions only: the reducers are pure functions that are receiving the current state tree and an action, and they know how the application will change to the next state. If we always pass the same parameters, we know the output of a pure function; in this case, the reducer will be always the same.

 

Let’s see React and Redux in action with our calculator example written for the last time with a different architecture.

 

How Redux Works

The starting point of any Redux project is usually the main application where we create the store object and we wrap our main view inside a provider object from the Redux library. See Listing.

Listing. App.js
export default class App{ constructor(){
const store = createStore(CalculatorReducer); const cont = document.getElementById("app");
ReactDOM.render(
<Provider store={store}>
<CalculatorContainer/>
</Provider>, cont);
}
}
let app = new App();

 

As we mentioned before, after creating the store and associating it to a specific reducer (Calculator Reducer), we are wrapping our main view (Calculator Container) inside a Provider object from the redux library.

 

Think about the Provider as an object that receives as input the store and it propagates it to all the container components inside an application in order to have complete access to it. 

 

Considering we have mentioned the container components, it’s time to move to the view part, where we need to distinguish between presentational components and container components.

 

The creator of Redux, Dan Abramov, wrote a post on Medium regarding this topic where is explaining the difference between the two types of components.

 

 To summarize Dan’s thoughts, in Redux we distinguish the presentational components as a component with the only scope of managing the look and feel of the view, more or less like the Passive View described in this blog.

 

Meanwhile, we identify the container components as the ones that can handle the presentational component logic like user interactions, having access to the store, and mapping the store values to the React component via a props object, similar to the Supervising controller of the MVP architecture.

 

This approach will lead to a better separation of concern and reusability of our components across different projects.

 

Presentational vs. Containers components in redux this is a very important topic. i strongly suggest having a look at this link to Dan Abramov's medium post on the presentational and containers components explanation: Presentational and Container Components – Dan Abramov – Medium

 

Based on what we have just described, it’s time to see what a presentational component looks like and how we handle the communication with the Redux framework.

 

In the calculator example, our presentational component code looks like that shown in Listing.

Listing. Calculator.jsx
export default class Calculator extends React.Component{ constructor(props){
super(props);
this.onBtnClicked = this.props.onButtonClicked;
}
createRow(id, ...labels){
let items = labels.map((value, index) => { return <li key={`${id}_${index}`}


})
return(

style={value === "AC"? acStyle : btnStyle} onClick={::this.onBtnClicked}>
{value}
</li>;

<ul key={id} style={ulStyle}>
{items}
</ul>
)
}
render(){
return(
<p>
<p style={displayStyle}>{this.props.result}</p>
{this.createRow("row1", "AC")}
{this.createRow("row2", "7", "8", "9", "/")}
{this.createRow("row3", "4", "5", "6", "*")}
{this.createRow("row4", "1", "2", "3", "-")}
{this.createRow("row5", "0", ".", "=", "+")}
</p>
);
}
}

We can immediately spot that we are focusing more on what our component looks like than what it does. The only method that is going to be used is the onButtonClicked method retrieved from the props object as well as the result property that will be used to show the calculation inside the calculator display p element.

 

The entire logic of this component, as well as the communication with the rest of the application, is made inside the container component, as shown in Listing.

 

Listing CalculatorContainer.js
const mapDispatchToProps = (dispatch) => { return {
onButtonClicked: (evt) => { evt.preventDefault();
let value = evt.target.innerHTML manageDisplayState(value, dispatch);
}
}
}
const manageDisplayState = (value, dispatch) => { switch (value) {
case "AC":
dispatch(reset()) break;
case "=":
dispatch(calculate()) break;
case "+":
case "-":
case "/":
case "*":
case ".":
dispatch(appendValue(value)); break;
default:
dispatch(appendValue(value)); break;
}
}

const mapStateToProps = (state) => { return{
result: state.result
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Calculator);

 

In this module, we can find many interesting things like the following:

The presentational component is created after calling the connect method. The connect method is used to “connect” the store to the component, and it returns a higher-order React component class that passes state and action into our component derived from the supplied arguments.

 

mapStateToProps is the method we use in order to translate the new state passed by the store into properties that will be rendered in the presentational component. mapDispatchToProps is the method we use to trigger all the dispatch actions happening inside our container component.

 

The dispatch method accepts an action that will be triggered and listed into the store and passed to the reducer.

 

Before we move to the reducer, it’s good to understand what an action is. Basically, an action is just a plain JavaScript object. Inspecting the CalculatorAction module, we can see it clearly in Listing.

Listing CalculatorActions.js
export function calculate(){ return {
type: CALCULATE
}
}


export function reset(){ return {
type: INIT, result: 0
}
}
export function appendValue(value){ return {
type: APPEND, toAppend: value
}
}

 

The actions are similar to commands where they bring with them the information needed to the reducers in order to change the current state to a new one. Usually, they have a property type where we define the type of action called from the store. dispatch method.

 

Finally, it is the turn of the reducer. The reducers are used when we need to change the application state because the action is notifying us that something happened inside the application but it doesn’t have the knowledge of how the application should change – that’s the reducer’s duty.

 CalculatorReducer.js
const calculation = (state = reset(), action) => { switch (action.type) {
case CALCULATE:
return {
type: action.type,
result: math.eval(state.result)
}
break;
case APPEND:
return {
type: action.type,
result: resultHandler(state, action.toAppend)
}


break; case INIT:
return {
type: action.type,
result: resultHandler(state, action.toAppend)
}
break; default:
return state; break;
}
}

In our reducer, we set as the default state the reset action that starts the application with the initial state (INIT in our switch statement).

 

Every time an action is dispatched, the store calls the reducer passing the current state and the action dispatched, and then the reducer is mapping the action to the next application state.

 

Redux is a very simple but effective state management library, and it’s interesting that there are many similarities with the MVP architecture – in particular for the relation view presenter like we have in Redux with the presentational component and its container.

 

Also in the redux ecosystem, there are other libraries that we can use in combination with Rx.js, for instance, or other reactive libraries.

 

Wrap-Up

In this blog, we have evaluated different architectures from the oldest one like MVC to the most recent one like Redux. We saw a clear evolution of them but with many references to the past principles. Often we spend a lot of time with a framework without asking us why the authors picked one decision over another.

 

I hope that this journey through the most famous architectures/frameworks available for the front-end development provided you some benefit in your future projects because I truly believe that it is very important to have a good knowledge of them for choosing the right one for a specific project.

 

Too often I have seen developers and architects always using the same architecture fitting any project inside it instead of using “the right tool for the right job”.

Recommend