What is RxJS?

RxJS is short for Reactive Extensions for JavaScript. Reactive extensions were originally developed by Microsoft as Rx.NET. Since that time, the Reactive extensions library has been implemented for several other languages, including Java, Python, Ruby and JavaScript. But that doesn’t really answer the question.

What is RxJS? According to the documentation, “RxJS is a library for composing asynchronous and event-based programs by using observable sequences.”

What does that mean? Think of RxJS as a way to manage data as it flows through time, similar to how Apple’s flow on a conveyor belt. First we collect. Apples are picked, hauled and loaded onto a conveyor, creating a stream of apples. Similarly, we use RxJS to send an HTTP request and receive the response, creating a stream of data. The stream is observable. We can watch it as items are added or emitted to the stream. We pipe the stream of apples through a set of operations. As each apple flows through, we transform the apple by cleaning it, filter it by quality or size, and process it of fixing a label, for example. Likewise, we pipe our data through a set of operations to transform, filter or process our data. Using query like operators, we combine streams to merge their results. In our apple example, we combine the green apple stream with a red apple stream to create a mixed bag of apples. Correspondingly, we combined a stream of customer data with the stream of invoice data to display a customer with their overdue invoices, and we can cache the stream. This one doesn’t fit as well into our apple metaphor. But when working with data, we may want to cache it in a service to reuse the data without another HTTP request.

Going back to the definition, we restate this as “RxJS is a library for composing observable streams and optionally processing each item in the stream using an extensive set of operators.” RxJS helps us better manage and manipulate the data needed in our application. There are other techniques for  managing asynchronous and event-based data.

A callback is a function that can be called back after an async operation is complete, but callbacks can be difficult to manage when working with nested async operations.

A promise is an object that may produce a single value sometime in the future. It can only handle a single emission and is not cancelable.

async/await is a special syntax that allows writing asynchronous code that looks synchronous. It also can only handle a single emission and is not cancelable.

Why use RxJS and not one of these approaches? Using RxJS has several advantages. RxJS provides a single technique for working with any type of data. We often work with multiple sources of data. Events from the keyboard, mouseover routes and data from various files, databases or third party APIs. With RxJS, we work with different data sources using the same techniques and operators. Our views often require data combined from several sources. We easily compose data with RxJS. RxJS can produce multiple values over time and uses a push model to notify our code when specific actions occur, making it easy for us to watch and react to user interactions or data changes. RxJS is lazy. Evaluation does not start until subscription. So we can create recipes that only execute when we need the result. For the best user experience we want to handle errors gracefully. RxJS has built-in error handling and with RxJS we can cancel asynchronous actions. For example, if a user clicks on Product A and then quickly clicks on Product B, we can cancel the request for Product A and only return Product B.

So many great advantages to RxJS that Angular built it in into several key features. For example, Angular uses RxJS in routing to watch for changes to route parameters, route data or router events. In Reactive Forms to watch for value changes as the user modifies input elements on a form and when communicating with the backend server, sending requests and receiving responses using HTTP client. That’s why Angular installs RxJS as part of its core set of libraries. We can expand our use of RxJS in our Angular applications to move towards more Reactive Development.

What is Reactive Development?

From Wikipedia, Reactive Development, also called Reactive Programming, is a declarative programming paradigm concerned with data streams and the propagation of change. As the user makes a selection, data is retrieved from a backend server or some other system status changed. That change is propagated and the application reacts appropriately updating the display or performing another action. In addition, reactive development is functional.

“The essence of functional reactive programming is to specify the dynamic behavior of a value completely completely at the time of declaration.” – Heinrich Apfelmus.

Reactive Development

A reactive system is quick to react to user interactions, resilient to failure with good error handling and reactive to state changes, meaning the code watches for change events and reacts, instead of procedurally calling methods.

Learning the Angular CLI

Exploring the Angular Command Line Interface (CLI)

Installing the CLI

sudo npm install -g @angular/cli
ng --version

Using the CLI

ng --help
ng build --help

Creating New Angular Projects

The ng new command

ng new app-name

New project generation options

ng new --help
ng new app-name --routing
ng new app-name --style=scss --routing --dry-run
ng new app-name --style=scss --routing --prefix=vsrao

Serving Angular Applications for Development

The ng serve command

ng serve --help
ng serve
ng serve --open

Customizing the development server

ng serve --port=8000 --open
ng serve --host=whatever.dev.company.com --open

Generating Angular Application Code

Creating new code with blueprints

With the Angular CLI you can generate the different entities used to build your application. You will be able to easily generate Components, Directives, Services, Pipes, Models and Interfaces, Route Guards and Modules. When generating a blueprint, your command will follow the following template:

ng generate [schematic] [name] [options...]
ng generate --help

Available schematics: application, class, component, directive, enum, guard, interface, module, pipe, service, universal and appShell.

Generating components and modules

ng generate component contact-list --dry-run
ng g c contact-list --dry-run
ng g c contact-list --dry-run --flat
ng g c contact-list
ng generate module shared
ng generate component shared/avatar --module=shared

Generating directives

ng generate directive shared/directives/non-numeric --module=shared

Generating services

ng generate service services/api
ng generate service services/api --module=app

Generating pipes

ng generate pipe pipes/phone

Generating models

ng generate class models/contact

Generating interfaces and enums

ng generate interface models/contact
ng generate enum models/contact-type

Generating route guards

ng generate guard auth

Building Angular Applications

A build pipeline for an Angular app

There are many steps involved in building an Angular application. Since Angular applications are written in TypeScript and ES6 and beyond, the build pipeline is quite involved. We need to Transpile TypeScript and ES6+ code, bundle our application into one file, or split across many, minify files by removing newlines and white space, mangle our application bundles to make files even smaller, and also generating source maps. Aside from that, we also need to deal with CSS and other assets, such as compiling from Sass to CSS, possibly inlining CSS, having scoped styles, and copying or inlining images. As you can see the process is very involved, but the Angular CLI takes care of all this for us using Webpack under the hood, all with a simple command, ng build. The ng build command also comes with several options.

Configuring different build options

By default, the ng build command runs a development build due to which the JavaScript bundles are not optimized meaning they are neither minified nor uglified for performance. Also the bundle names do not contain a hash for cache busting.
A production build can be run using ng build --prod. For generating source maps in a production build we need to use the ng build --prod --sourcemap command. Lastly, if you wish to analyze the generated bundle files, using a tool such as webpack bundle analyzer use the ng build --prod --stats-json command. Running this command will generate a stats.json file, which you can then upload on webpack.github.io/analyse/ . On this site, you can analyze the different bundles that the build pack run generated for you. You can analyze chunks, the assets, and see the size of each of them.

Setting up build scripts

In the package.json file, we can setup the below npm scripts:
"build:dev":"ng build --stats-json"
"build:prod": "ng build --prod --stats-json"
Setting up npm scripts will make automation much easier.

Running Tests

Built-in test runners and scaffolding

When you create an Angular application using the CLI, a testing pipeline is already set up for you. To run your unit tests, a karma configuration file, karma.conf.js is generated. Karma is used as a test runner using jasmine as a testing framework, and is set up, by default, to run your tests in Chrome. Additional setup can be seen in test.ts. Essentially, this provides additional setup to initialize the Angular testing environment. You can write your tests in TypeScript and the CLI will take care of transpiling that for you.

The ng test command

In order to run your unit tests, you use the ng test command. This will take all of your spec files, transpile them in memory, and run your unit test in Chrome.

Test run options

Running the ng test command runs the test in watch mode. However, if you prefer not to do that, you can use a single run flag. By running the ng test --single-run command the test will only run once and then exit. This will be needed in a Continuous Integration environment.
You can also generate code coverage reports when running your tests. To do so, you need to use the code coverage flag. Running ng test --single-run --code-coverage command will not only run your tests but will also generate code coverage reports using Istanbul. Once it is complete, it will create a new coverage folder, with an index.html page for your report.

Ejecting from the Angular CLI

The tooling provided by the Angular CLI is quite extensive. It can generate applications, application code, and also set up build and testing pipe lines for you. However, it is not uncommon for a development team to ask specific needs over the build process, in order to have finer control. It is for these purposes that the Angular team created an eject feature. You can use this feature if you feel that you want to manually take care of running and building your application. To do so, you can use the ng eject command.

Conclusion

The Angular CLI is truly a great tool that will allow you to be productive building Angular applications. I recommend subscribing to notifications on this GitHub repository – https://github.com/angular/angular-cli/, as it will allow you to keep up to date with new features and be notified of new releases. The Angular team have some great things planned for the CLI. I also recommend subscribing to the official Angular Blog – https://blog.angular.io/ for keeping up to date.