Angular in the Real World

Angular is one of the more popular JavaScript frameworks in use today. With the backing of a huge company (Google) and the widespread use in the corporate world, it certainly deserves consideration when you are planning your next app development. In this blog post, I'll take a quick look at the key features of Angular.

Angular was created by Google and was originally released in 2010 as AngularJS - the 1.x version. The initial release of the Angular 2.x version was on September 14, 2016. While the initial release of preview alpha and beta versions existed in 2015, fall 2016 is when we started to see some real traction in its use.

The second major revision was initially referred to as AngularJS 2 or 2.0 but was later rebranded to just "Angular" for release 2.0 and higher. The 5.x version in beta was just published at the time this was written. If you feel something is missing, it's version 3 - because it was skipped. While Angular was on release 2.0, the Angular router was already on version 3, so in order to sync everything up, they jumped from 2.x into 4.x.

Angular is a free, unlicensed library, so there is no perfect usage statistics - but there are several places we can look to get a good idea. Angular has over 32,000 stars on GitHub and over 1 million npm downloads per month at the time of writing. Some of this traffic might, of course, be from development machines or mirrors, but these are good quick stats to get an idea of just how popular the library is.

Angular Usage Statistics

32K+ stars on GitHub.

1 million+ npm downloads per month.

Angular is obviously seeing a lot of use. But what is Angular? Let's take a quick look at the core concepts involved in Angular. We will look at 4 main things: components, dependency injection, property bindings, and TypeScript.

Angular Core Concepts

Components

Dependency Injection

Property Bindings

TypeScript

Components

Almost everything in Angular is a component. Even the application itself, at the root of the application, is actually a component. Whether it's a custom element or an overall single page application, everything is a component or a set of components. You have a component tree going from that root out to everything that we have to work with out-of-the-box from Angular, or something that we create ourselves. There are other aspects of Angular that aren't components, but much of what we as developers write deals specifically with components: Data flows in through an input property, and out through an output property.

In the example below, we see a component that has some bindings and we have a selector for it that's called "my-app." It can be used later in another component with my-app as the tag. This gives us a way to take a piece of functionality and isolate it and make it its own module. From there, we can reuse that either in other, similar, modules or just in the main overall application.

Every component has a lifecycle that's managed by Angular. If we create a component, we automatically take advantage of the lifecycle that Angular provides. From that lifecycle, there are various hooks that we can take advantage of and each component has this set of hooks. They are events that we can essentially subscribe to in order to be able to do something within that component. Just by declaring and creating a component, we automatically have this lifecycle that Angular applies, whether it's when we initialize the application and the view and the component, or when we destroy the components.

Component Hooks

ngOnChanges()

ngOnInit()

ngDoCheck()

ngAfterContentInit()

ngAfterContentChecked()

ngAfterViewInit()

ngAfterViewChecked()

ngOnDestroy()

Input properties are essentially the way that we deal with and allow for the transfer of data between one component to the next. For example, below we can see that we have an image tag that we can bind to the source in a couple of different ways.

The first approach using the double bracket syntax here is interpolation. That can be used if your property is a string. In this case, myProfilePic, for example, is a URL. We can very easily bind to it through these double brackets. Using the square brackets on the attribute can be used in scenarios where it's not a plain string. If we want to have a return value that pops back from the function or whatever it might be, we could potentially use something like that here.

<img src="{{ myProfilePic }}">

<img [src]="myProfilePic">

<img bind-src="myProfilePic">

The bind-attribute is actually the same approach as using the brackets, but this might not be used since it can be a little bit easier to read with the square brackets when we're dealing with attributes that we're probably pretty used to.

In the example below, we're working with the same component that we had above. This is an image tag, but this will be the same as if you passed some particular data from a component that is available.

Output properties are usually events submitted by the component. In the example below, we see that we have a button where we have the ability to vote, and we can vote true or false. We see that, below, we have an @outputtag here on the onVoted variable, which is a new event emitter. If I'm in a child component and I want to be able to push something that happens within that child component and I want the parent to be able to react to it, I can pass in an event and say "okay, when this event happens, let's emit this event," and then it will push data back out into the parent.

Instead of having two-way binding between a parent component and a child component, Angular and a lot of other frameworks generally deal with one-way binding. Two-way is reserved for input elements, and then we also tend to work with events to emit something back, or maybe even a service layer in order to be able to push data and keep state. Generally, we're not doing a lot of two-way binding between components.

Dependency Injection

To understand the concept of dependency injection, let's look at a scenario from the Angular documentation. In the example below, we have a class, car, that has an engine, tires, and a description. Then, in the constructor, when this gets initialized, we have this.engineequals new Engine, and this.tiresequals new Tires. Every single time that we create a new car, we are creating its own copy of engine and tire.

This is kind of brittle, however. What if the engine or tires need changing, and what if we want to have a different set of tires on the car, or what if we want to have a slightly different engine in each individual car? We can't really do that because we're constantly creating a new version of engine and a new version of tireshere in this constructor without being able to change that. We would more or less have to create a bunch of different car classes with these different engines. There's no flexibility in customizing a car, engine, or a tire at any point throughout this kind of setup.

With dependency injection, we can take the constructor and pass in an engine and pass in tires.

Now we're consuming engine and tires, not necessarily creating them. This allows us to pass in instances.

let car = new Car(new Engine(), new Tires());

We can, for example, either pass in a new engine or a new tire, or if we already have existing versions of engine and tire, we can pass those in. We can create a brand new engine class that allows us to pass in the number of cylinders that we want to be able to have for the engine, and we can now create a new car using that syntax.

Dependency injection is not unique to Angular, but it is something that we see constantly across Angular applications and is a concept that we should grasp when we start learning Angular.

TypeScript

TypeScript is a typed superset of JavaScript that compiles to plain JavaScript. It brings static typing and structuring to JavaScript. It is intended to help build large and complex web applications and is often picked by enterprise groups. It's very familiar to folks in a development environment, and many Java developers also like that it's a statically typed language and like to pick this up on the client side of things.

Angular has standardized on TypeScript from the beginning. You can work with plain JavaScript if you want to, but TypeScript tends to be increasingly popular. You'll see a lot of samples running on TypeScript. A lot of the community is writing blogs, articles, resources, and sample applications in TypeScript, and it frequently goes hand-in-hand with Angular.

Getting Started

The easiest way to get started is through the Angular CLI. Angular can be complicated to setup from scratch because it has to be customized a bit to be able to output the application. You also probably need to work with something like Webpack, Babel, et cetera, in order to be able to go from TypeScript and compile down to JavaScript. We need to have a compilation step because of this and to be able to actually release this on to the client. The CLI helps us create new projects, sets everything up for us (even unit testing). Out of the box, you can set it up with Webpack.

All that you need to do is use npm. You can just do npm install -g @AngularCLI. Then you have access to the command line of ng, so you can use ng new app, cd my app, and ng serve -open which allows us to launch the application in the browser.

You can use ng serveas well, but --openbrings it up in the current browser.

ng-serve --open

What Next?

We covered a lot of content quickly to present a "taste" of Angular, and we have not done more than scratch the surface. However, this should be enough to give everybody a high-level look at what we have available within Angular.

Now that you have had a quick look at Angular, is Angular the right choice for you? There are other frameworks that are very popular - React and Vue in particular. Angular is very different than React or Vue, and whether or not it is the right choice for you depends on a number of factors.