Angular Components

Luis Miguel Fernández
Elements blog
Published in
7 min readJul 7, 2016

Written by Luis García Estrades and Luis Miguel Fernández of the Elements Barcelona office.

Last weekend the first AngularCamp in Spain took place at the at Disseny Hub in Barcelona (the new center of Barcelona’s Institute of Culture which works to promote better understanding and design world usage) and, therefore, a small group of Elements BCN’s front-enders attended. The event was organized by the AngularBeers community and the University of Barcelona.

We were the first ones in line to enter this architectural masterpiece, and once we got our accreditations, we were also the first ones to enjoy a brief breakfast and start doing some networking with the rest of the attendees. Throughout the day we enjoyed the stay in such a splendid place and had the opportunity to share opinions with the speakers and the attendees, even with a beer after the schedule.

The conference was focused on one of the most popular JS frameworks in the market: Angular. More precisely, the new version — Angular 2, which has a lot of possibilities of becoming the de-facto most used front-end framework. Also, it is super new as its last release candidate was published in May 2016. This, of course, is in accordance with the fast paced developments in the front-end space the last few years.

As stated above, all conferences revolved around Angular 2-related technologies and how-to’s, but we will try to stick to one of the most basic topics of the event: Angular Components.

Components: Tendencies in modern front end web development

The world of web development changed tremendously since 2009, which was the year when Angular 1 was initially released. Among the trends that continually rose during this time was the use of web components. When used, web components allow developers to gain total control over their web page by providing highly functional templates that are encapsulated within custom HTML selectors.

“The components model allows for encapsulation and interoperability of individual HTML elements.”

Many people understood that components were the way to go if you wanted to build good and robust web applications, so many frameworks emerged focusing on this very paradigm, and existing ones started to adapt to it.

So, after noticing the power of components, even the Angular framework migrated its directives (which were their first approach to a component), controllers, and scope flow to components in Angular 2. They are even updating Angular 1 to adapt to this, so from 1.5 onward, components can be used as well.

Types of components

Most components are dumb components, aka presentational components or stateless components. They are the components that actually render the UI. They put all the data and all the controls on the screen. But they do not know where the data comes from, or what logic should be executed when the user interacts with it. They merely get the data as inputs and send out user actions as outputs. Data down, actions up.

A smaller number of components are smart components or container components. They are used to wrap dumb components, and they are the things that actually know where data comes from and what it means to make changes to that data. In Angular apps, these components are the ones that talk to services to read and write data. They also handle all the asynchronous acrobatics that goes along with it.

So, in the end we’ve got:

Stateless components:

  • Are concerned with how things look.
  • May contain both presentational and container components inside, and usually have some markup and styles of their own.
  • Have no dependencies on the rest of the app.
  • Don’t specify how the data is loaded or mutated.
  • Rarely have their own state (when they do, it’s UI state rather than data).
  • Examples: Page, Sidebar, Story, UserInfo, List.

Container components:

  • Are concerned with how things work.
  • May contain both presentational and container components inside but usually don’t have any DOM markup of their own except for some wrapping divs, and never have any styles.
  • Provide the data and behavior to presentational or other container components.
  • Are often stateful, as they tend to serve as data sources.
  • Examples: UserPage, FollowersSidebar, StoryContainer, FollowedUserList.

The benefits of this approach are clear:

  • Better separation of concerns. You understand your app and your UI better by writing components this way.
  • Better reusability. You can use the same presentational component with completely different state sources, and turn those into separate container components that can be further reused.
  • Presentational components are essentially your app’s “palette”. You can put them on a single page and let the designer tweak all their variations without touching the app’s logic. You can run screenshot regression tests on that page.
  • This forces you to extract “layout components” such as Sidebar, Page, ContextMenu instead of duplicating the same markup and layout in several container components.

Angular first insight of components, the good ol’ directives

Angular is the father of what we know now as web components. It shined as a development framework with the well-known directives. These offers a new way to inject new HTML tags into the DOM, which are rendered by the browser subsequently.

Directives were the first approach of what we actually know as web components and, transformed the general architecture of the FE projects from a more traditional design to an isolated web component.

Directive vs component in Angular

Why directives were difficult

  • One of the first bumps that an Angular beginner encounters is learning the flexibility of the directives, their different settings and usages.
  • The concept of two-way data binding, one of the Angular core concepts that made it so famous, everyone agrees that two-way data binding is a really good feature, but, when the application becomes more complex, the digest cycles become heavy and this sometimes can lead to a unresponsiveness feeling in the UI. More about the two-way data binding in the docs.
  • It’s hard to investigate a certain topic through the docs and sometimes it is better to just look around in the source code.
  • There are too many properties to configure a directive and also life cycle functions that can be defined that it’s easy to overwhelm the developer.

More about all the properties and the life cycle in the docs.

What are directives for?

Directives and templates/controllers are not necessary anymore in a component based architecture, however, the API remains consistent for backward compatibility. Use a Directive for binding custom behavior to existing DOM.

A directive decorates the DOM, adding behavior or extending the existing one, directives should be used when you need to conduct DOM manipulation outside of the Angular event loop and core.

What are components for?

Components are not “helper” methods that extend the DOM, they create new HTML via the `template` or `templateUrl` properties. They are used to create components as part of a component architecture and should be used with one-way data binding expressions.

They are easier to learn and make the transition to Angular 2 more intuitive. Also they advocate best practices and common default behaviours like default isolated scope, $onInit life cycle hook and restricted to element.

Component vs @component

Let’s show a little counter component to see the different flavours, it only increments or decrements a counter.

In Angular 1.5 the syntax is as it follows:

angular.component('counter', {
bindings: {
count: '='
},
controller: function () {
function increment() {
this.count++;
}
function decrement() {
this.count--;
}
this.increment = increment;
this.decrement = decrement;
},
template: `
<div class="counter">
<input type="text" ng-model="$ctrl.count">
<button type="button" ng-click="$ctrl.decrement();">-</button>
<button type="button" ng-click="$ctrl.increment();">+</button>
</div>
`
});

and in Angular 2 we have:

import {Component} from '@angular/core';

@Component({
selector: 'counter',
template: `
<div class="counter">
<input type="text" [(ng-model)]="count">
<button type="button" (click)="decrement();">-</button>
<button type="button" (click)="increment();">+</button>
</div>
`
})
export default class CounterComponent {
constructor() { }

increment() {
this.count++;
}
decrement() {
this.count--;
}
}

The first thing we notice is the usage of typescript per default on Angular 2 and the fact that in Angular 1.5 a component is an object and in Angular 2 it’s a decorator applied to a class.

Conclusion

Web components are a key feature in modern web application development. They prove to be easy to understand, easy to learn, more “ravioli”-friendly (loosely-coupled components), they improve the readability and maintainability of the project, and, of course, the testing.

Therefore, various technologies adopted them as core features in the development process for a component-based architecture project.

It seems clear they came to stay and it’s wise to get used to using them whenever necessary.

Follow Elements on Facebook, Twitter and LinkedIn!

Originally published at www.elements.nl on July 7, 2016.

--

--

Luis Miguel Fernández
Elements blog

I’m an early investor, web developer and gamer trying to reach financial independence to spend time in the things I love.