Angular Best Practices

Angular Best Practices

Angular Best Practices - In this article, we are going to show what we consider to be the best practices in Angular while develop the client side project in this framework...👏👏👏👏👏

Angular Best Practices - In this article, we are going to show what we consider to be the best practices in Angular while develop the client side project in this framework...

If you have been around in the last few years in the development field, I am sure you must have come across the name Angular at-least once. In this article, we are not only going to talk about what Angular is, but some of the best practices that a developer should keep in mind to keep the project efficient and the code easier to manage and debug.

What is Angular?

Angular is a modern MVVC framework and platform that is used to build enterprise Single-page Web Applications (or SPAs) using HTML and TypeScript. Angular is written in TypeScript. It implements core and optional functionality as a set of TypeScript libraries that you import into your apps. Angular is an opinionated framework which means that it specifies a certain style and certain rules that developers need to follow and adhere to while developing apps with Angular, therefore you need to learn Angular and the various components that make up an Angular app.

Angular vs AngularJS

A lot of beginners get confused with so many different versions out there for the same framework. You must have heard AngularJS, Angular 2, Angular 4, Angular 5, Angular 6 and now Angular 7. Well, in reality, there are two different frameworks - AngularJS and Angular.

AngularJS is the JavaScript-based web development framework which was first released in 2010 and is maintained by Google. Later, in September 2016, Angular 2 was announced which was a complete rewrite of the whole framework using TypeScript, a super-set language of JavaScript.

Since modern browsers (as of now) do not understand TypeScript, a TS compiler or transpiler is required to convert the TS code to regular JS code.

**Why Angular? **

Why do we use Angular that uses TypeScript as the primary programming language when it comes with the overhead of transpilation? Well, the answer lies in the list of advantages that TypeScript offers over traditional JavaScript. With TypeScript, developers can use data types, syntax highlighting, code completion all the other modern features that help them code faster and more efficient. Since TypeScript is an object oriented programming language, developers can use the advantages of classes, objects, inheritance and similar features that all other OOPLs offer.

Angular, therefore, is the framework that uses TypeScript as the primary programming language. Since the Angular team opted for semantic versioning, Angular 2, 4, 5, 6 and 7 are all the versions of the same framework, each version being better than the previous one, while AngularJS is a completely different framework that uses JavaScript as the primary programming language.

Recommended Best Practices

Next, we will go through some of the best practices that a developer should follow to keep the project easier to manage and debug. Although, there are no hard rules regarding these best practices, most developers follow them. You may have your own coding styles and that is completely fine too.

Using the power of TypeScript

Angular is written using TypeScript which means that all the code that you will be writing to build your amazing web-app will also be written using TypeScript. One key point to note here is that all the JavaScript code is valid TypeScript code. While it is recommended that you use TypeScript code all along, you can even you JavaScript code, if you will.

Using TypeScript offers you certain advantages as you are able to define types on the properties and variables, you can define classes & interfaces and utilize the power of interfaces and unions.

Specify types for all variables. This helps you prevent other developers working on the project from storing wrong information in the variable. For example, if a variable called age is of the type number, it can only store numerical values. If another developer writes the code to store the value of any other types, for example, a string, the code editor will warn the developer and the compilation process will also be able to spot the error in the code. These errors won’t leak into the runtime.

Classes in object oriented programming languages are used to contain data members and member functions related to a particular citizen in the application. Be it a product, a user or something else like that. Always create classes to represent these citizens in your applications. Encapsulate all the functionality related to these objects within these classes. This helps keep the consistent and maintainable when a large team is working on the project.

class User {
first_name: string;
last_name: string;
email: string;
constructor(f_name: string, l_name: string, email: string) {
this.first_name = f_name;
this.last_name = l_name;
this.email = email;
}
sendMail() {
// method to send an email to the user
}
}

Consistency brings productivity into the picture as well. Developers don’t have to worry as much about if they’re doing it the “right way”.

Create models to represent objects in your data that can be more complex than simply a string or a number. Using models allows you to use the help offered by the Code Editor you are using. Most errors that are likely to be introduced because of typing can be prevented because you do not need to remember the names of properties inside the model as the Code Editor will suggest the names as you type.

If you have worked with MVC frameworks before, you know that you declare types in a model which can then be reused throughout the rest of the application. With TypeScript, front-end applications can now benefit from strongly typed models. Consider a simple model for a user as below.

export interface User {
  name: string = 'Angular';
  age: number = 0;
}

According to the Angular Style Guide, models should be stored under a shared/ folder if they will be used in more than one part of your application.

A lot of times, developers depend on APIs and the data returned by the APIs. They retrieve the data, process it and present the data to the user in a nice and clean UI. It is possible that the APIs are not always perfect or some field of the API may not always contain the expected values or the values in the expected format.

TypeScript allows intersection types. This allows you to create variables of a type which is a combination of two or more types. Let’s have a look at an example.

interface Student {
    roll_number: number;
    name: string;
}
interface Teacher {
    teacher_id: string;
}
type A = Student & Teacher;
let x: A;
x.roll_number = 5;
x.name = 'Samarth Agarwal';
x.teacher_id = 'ID3241';

In the above code, the new type A is a combination of types both Student and Teacher and will therefore contain the properties of both types.

While intersection creates a new type with the combination of the provided types, union, on the other hand, allows you to have a type either of the several types provided as arguments. Let’s look at an example.

age: string | number;

In the code snippet above, the age variable can store a value of either the type string or number. So, both the following values will be fine.

this.age = 12;
this.age = 'twelve';

Use the Angular CLI

Angular CLI is one of the most powerful accessibility tools available when developing apps with Angular. The Angular CLI makes it easy to create an application that already works, right out of the box. It already follows all the best practices!

The Angular CLI is a command-line interface tool that is used to initialize, develop, scaffold, maintain and even test and debug Angular applications. You can use the tool directly in a command shell.

Instead of creating the files and folders manually, try to always use the Angular CLI to generate new components, directives, modules, services, pipes or even classes. Angular CLI updates the required module files and generates required files and folder. It also creates the required files for unit testing the components and directives. This maintains the uniformity of structure across the application and helps easily maintain, update and debug the project.

The CLI also allows you to use the development server to test the applications locally and then build the production build of the application for deployment.

To stay updated with the latest version of the CLI, you can use the following command.

npm install @angular/cli -g

You can also check the version installed on your system using the following command.

ng version

Naming Conventions

According to the Angular style guide, naming conventions are hugely important to maintainability and readability. Following general naming conventions are specified by the Angular style guide.

  • Do use consistent names for all symbols.
  • Do follow a pattern that describes the symbol's feature then its type. The recommended pattern is feature.type.ts.
  • Do use dashes to separate words in the descriptive name.
  • Do use dots to separate the descriptive name from the type.
  • Do use conventional type names including .service, .component, .pipe, .module, and .directive. Invent additional type names if you must but take care not to create too many.

Why? Naming conventions help provide a consistent way to find content at a glance. Consistency within the project is vital. Consistency with a team is important. Consistency across a company provides tremendous efficiency.

Why? The naming conventions should simply help find desired code faster and make it easier to understand.

Why? Names of folders and files should clearly convey their intent. For example, app/heroes/hero-list.component.ts may contain a component that manages a list of heroes.

The purpose of the above guidelines is to ensure that just by looking at the filename, one should be able to infer the purpose and type of the contents of the file. For example, files with filenames hero.component.ts and hero.service.ts can be easily identified as being the files for the component and service for something called a hero in the project, respectively.

Note: If you are using the Angular CLI (which you always should), the file names will be taken care of automatically by the CLI.

Single Responsibility Principle

The single responsibility principle is a computer programming principle that states that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by the class.

Apply the single responsibility principle (SRP) to all components, services, and other symbols. This helps make the app cleaner, easier to read and maintain, and more testable.

According to the style guide, functions should be limited to 75 lines of code. Any method larger than that should be broken down into multiple files or methods. Each file, on the other hand, should be limited to 400 lines of code.

Creating one component per file makes it far easier to read and maintain the components as the application grows over time. This also helps avoid collisions with teams in source control. This also prevents any hidden bugs that may often arise when we combine multiple components in a file where they may end up sharing variables, creating unwanted closures, or unwanted coupling with dependencies. A single component can be the default export for its file which facilitates lazy loading with the router.

The key is to make the code more reusable, easier to read, and less mistake prone.

Breaking down Components

This might be an extension of the Single responsibility principle not just to the code files or the methods, but to components as well. The larger the component is, the harder it becomes to debug, maintain and test it. If a component is becoming large, break it down into multiple, more manageable, smaller components, dedicating each one to an atomic task.

In such a situation, if something goes wrong, you can easily spot the erroneous code and fix it spending less time in spotting the issue.

Look at the following code for a component called PostComponent which can be used to display various parts of the post including the title, body, author’s information and the comments made by people on the post.

<div>
<h1>
<post-title></post-title>
<h1>
<post-body></post-body>
<post-author></post-author>
<post-comments><post-comments>
</div>

The component contains multiple components and each of these components only handles a small task. We could have had one gigantic component instead of having 4 different ones but that would have been so hard to maintain and read.

It is also a good practice to keep minimal code within the component. Component should handle the job of displaying the data to the user in a nice and clean way while the responsibility of data retrieval should be outsourced to a service. The component should receive the data either as an input or use the service to retrieve the data.

Change Detection Optimizations

When you scaffold a brand new Angular application, the change detector seems magically fast. As soon as you change the value of a property on the click of a button or something like that, the view updates almost in real-time without any delays.

But, as the application grows, things may start to lag a bit. If you have drag & drop in your interface, you may find that you’re no longer getting silky-smooth 60FPS updates as you drag elements around.

At this point, there are three things you can do, and you should do all of them:

  • Use NgIf and not CSS - If DOM elements aren’t visible, instead of hiding them with CSS, is it a good practice to remove them from the DOM by using *ngIf.

  • Make your expressions faster. Move complex calculations into the ngDoCheck lifecycle hook, and refer to the calculated value in your view. Cache results to complex calculations as long as possible.

  • Use the OnPush change detection strategy to tell Angular there have been no changes. This lets you skip the entire change detection step on most of your application most of the time and prevents unexpected change detection steps when they are not required at all.

This saves the trouble to empirically determining all properties of all Angular Components and Directives for changes and therefore improves a lot on the performance of the application.

Build Reusable Components

It is a rule never said - build reusable components. If there is a piece of UI that you need in many places in your application, build a component out of it and use the component.

This will save you a lot of trouble if, for some reason, the UI has to be changed a little bit. In that case, you do not go around changing the UI code in all 100 places. Instead, you can change the code in the component and that is it. The changes will automatically be reflected in all the usages of the component throughout the application.

Reusing a component in multiple places may require the component to change itself based on the context and adjust accordingly. For this, you may have to use property and event bindings to pass inputs to the components and receive output events from the components, respectively.

API code in a Service

Components consume Services.

A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well. Service is a broad category encompassing any value, function, or feature that an app needs.

This again connects to the Single responsibility principle and keeping the components lean. In Angular, there is a clear line of separation between components and services, and this is done to increase modularity and reusability. When a component's view-related functionality is separated from other kinds of processing, it makes the component classes lean and efficient.

Certain tasks can be delegated to services by components, such as fetching data from the server, validating user input, or logging directly to the console. If we define these tasks in a service, we are making this reusable across all the components in the application and more. However, Angular doesn't enforce these principles but Angular does help you follow these principles by making it easy to break down your application logic into services and making those services available to components through dependency injection.

export class APIService {
  get() {
// code to get the data from the web service or API
}
  post(data: any) {
// code to send the data to the web service or API
}
  update(data: any) {
// code to update the data
}
}

The above code is a representation of a service that interacts with the external API on behalf of the application. This service can be used to get the data from the API, send the data to the API and update any existing data on the server. Other components use this service to handle sending and receiving of the data.

Using trackBy in NgFor

The NgFor directives is used to loop over a collection (or an array) in your application to render a piece of UI repeatedly. The following snippet is a typical implementation of rendering a collection using NgFor directive.

<ul>
<li *ngFor="let item of collection;">{{item.id}}</li>
</ul>
And let’s use the following code in the TS class to change the elements in the collection every 1 second.
import { Component } from '@angular/core';
@Component({
 selector: 'my-app',
 templateUrl: './app.component.html',
 styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
 collection = [{id: 1}, {id: 2}, {id: 3}];
 constructor() {
   setInterval(() => {
      let randomIndex = parseInt(((Math.random() * 10) % 3).toString());
      this.collection[randomIndex] = {
        id: parseInt(((Math.random() * 10) % 10).toString())
      }
    }, 1000)
 }

}

If we change the data in the collection, for example as a result of an API request or some other complex logic within the application, we may have a problem because Angular can’t keep track of items (not able to identify each individual element) in the collection and has no knowledge of which items have been removed or added or changed.

As a result, Angular needs to remove all the DOM elements that are associated with the data and create them again. That means a lot of DOM manipulations especially in case of a big collection, and as we know, DOM manipulations are expensive. This is okay if you have a small app or the collection only has a few elements but as the application grows, thus can cause performance issues in the application.

The solution is to always use trackBy whenever you use NgFor directive. Always ensure that you pass in a unique value to the trackBy so that Angular can uniquely identify each element in the collection using the unique value. In the following snippet, we use the id.

<ul>
<li *ngFor="let item of collection; trackBy: id">{{item.id}}</li>
</ul>

If you run the above code, and look at the DOM using Google Chrome Inspector, you will find that only the list item that has changed is re-rendered. All the other list items are unchanged.

The trackBy also takes a function as the argument which takes the index and the current item as arguments and needs to return the unique identifier for this item.

Lazy Loading Modules

Lazy loading is a technique in Angular that allows you to load JavaScript components asynchronously based of currently activated route. It is a feature that could help you a lot with large and heavy applications.

Since lazy loading breaks down the application into multiple modules (logical chunks of code) and loads those modules only when they are required by the user (depending on where the user navigates within the application), it reduces the initial load times of the application since less KBs are loaded when the application is loaded first. As the user navigates within the application, more chunks are loaded as and when required. Angular router has full support for lazy loading Angular modules.

Using Async Pipe

I always use async pipe when possible and only use .subscribe when the side effect is an absolute necessity.

You must have heard that the AsyncPipe unsubscribes from Observables as soon as the component gets destroyed. But did you also know it unsubscribes as soon as the reference of the expression changes?

That’s right, as soon as we assign a new Observable to the property that we use the AsyncPipe on, the AsyncPipe will automatically unsubscribe from the previous bound Observable. Not only does this make our code nice and clean, but it’s also protecting us from very subtle memory leaks.

Environment Variables

When we build projects using Angular (or any other technology for that matter), it’s common for developers to have multiple application versions that target different environments i.e. development and production. Each environment will have some unique environment variables i.e. API endpoints, app versions, datasets, etc. Angular provides environment configurations to declare variables unique for each environment.

By default angular supports two environments – production and development.

Inside the environment directory, there are two files, environment.ts and environment.prod.ts. While the first file contains the environment configuration and variables for the development environment, the second one contains the same for the production environment.

You can even add more environments, or add new variables in the existing environment files.

// environment.ts environment variables
export const environment = {
  production: false,
  api_endpoint_root: 'https://dev.endpoint.com'
};
// environment.prod.ts environment variables
export const environment = {
  production: true,
  api_endpoint_root: 'https://prod.endpoint.com'
};

Maintaining these variables helps a lot when something changes, for example, the API URL for the endpoint and when you build your application for a particular environment, the variables changes are applied automatically.

Always Document

Last, but not the least - Alway document your code as much as possible.

Writing comments within the code helps other developers involved in the project development a lot and understand the purpose and logic of the written code. It helps manage the code and adds to the readability of the code.

It is a good practice to document the use and role of each variable and method. For methods, each parameter should be defined using multi-line comments and it should also be defined what task exactly the method accomplishes.

What’s new?

We do not know much about the latest version of Angular, 8 (8.0.0-beta.8), yet but like any other major update, this version will be better, faster and result in a smaller build than the previous versions. It has improvements and fixes over the previous version of Angular.

How to Use Cookies in Angular for Storing user’s Credentials

How to Use Cookies in Angular for Storing user’s Credentials

In this post, I will be explaining about using Cookies in Angular for Storing user’s Credentials

By using cookies we are going to store the user's login data, if the user's credentials are valid, then it will be directed to the Dashboard page.

In this post, I will be explaining about Angular cookies. So what is a cookie? Cookies are like a small package of information that is stored by the user’s browser. Cookies persist across multiple requests and browser sessions that should be set so that they can be a great method for authentication in web applications. Sometimes we will have some queries about which is to be used -- either local storage or cookies? Before that, I like to say that the cookies and local storage serve different purposes.

The local storage can be read on the client-side, whereas the cookies are being read on the server-side. The biggest difference is the data size is about to store, the local storage will give more space to store, whereas the cookie is limited by the size of to store.

As I said above the cookies are used on the server-side whereas the local storage is used on the client-side. The local storage is a way of storing the data in the client’s PC, by saving the key/ value pair in a web browser with no expiration date. We will discuss about using local storage in the next article, so coming to the point, as I said the cookies are a kind of small file that are stored on the user’s browser.

The cookie is a small table which will contain key and data values so, by using this it will be very useful to carry information from one session to another session. Once we are about to store data on the server without using cookies then it will be difficult to retrieve a particular user’s information without a login on each visit to that website.

So far we have seen about the overview of a cookie and the usage of it. Now in this article, I will explain about storing the username and password of a static user in the cookie table. So, I have created two components, namely the login component and dashboard component, and I have set a static username and password in authservice.ts file.

So, when a user logs in to the login form by providing his user’s credentials the authservice checks the input and redirects the user to the dashboard if the user’s credentials are valid. If the user’s credentials are not valid it will alert by throwing enter valid email or password. And if the dashboard page is being accessed by unauthorized usage the page will be redirected to the login page automatically.

Setting up

In order to use cookies in Angular, we need to install the Angular cookie library by using the following npm package manager.

npm install ngx-cookie-service –save

After installing the package manager, we need to import the cookie service in the inside of our modules.

I have used the ng zorro library UI for form design, and you can find more information about ng zorro from the following link. The next step is to design a login form. So, open login.component.html file and replace the following code.

<form fxFill #Login="ngForm" (ngSubmit)="onsubmit()">  
    <div nz-row>  
        <div nz-col nzMd="12" nzXs="24">  
            <hr />  
            <nz-form-item>  
                <nz-input-group>  
                    <div nz-col nzMd="11" nzXs="8">  
                        <nz-input-group nzPrefixIcon="user">  
                            <input type="text" nz-input name="Login_name" placeholder="User Name" id="userName"  
 
#userName="ngModel" [(ngModel)]="Obj.username">  
                            </nz-input-group>  
                            <div *ngIf="Login.submitted && userName.errors" style="color: red">  
                                <div *ngIf="userName.hasError('required')">  
  
Login ID is required  
  
</div>  
                            </div>  
                        </div>  
                    </nz-input-group>  
                </nz-form-item>  
                <nz-form-item>  
                    <div nz-col nzMd="11" nzXs="8">  
                        <nz-input-group nzPrefixIcon="lock">  
                            <input type="password" nz-input name="user_password" placeholder="Password"  
  
id="password" #password="ngModel" [(ngModel)]="Obj.password">  
                            </nz-input-group>  
                            <div *ngIf="Login.submitted && password.errors" style="color: red">  
                                <div *ngIf="password.hasError('required')">  
  
Password is required  
  
</div>  
                            </div>  
                        </div>  
                    </nz-form-item>  
                    <div class="button">  
                        <button nz-button nzType="primary">  
  
submit  
  
</button>  
                    </div>  
                </div>  
            </div>  
        </form>  

Now open login.component.ts file and replace the following code in it.

import {  
    Component,  
    OnInit  
} from '@angular/core';  
import {  
    FormGroup  
} from '@angular/forms';  
import {  
    AuthService,  
    User  
} from '../services/authservice.service';  
import {  
    Router,  
    ActivatedRoute  
} from '@angular/router';  
import {  
    CookieService  
} from 'ngx-cookie-service';  
@Component({  
    selector: 'nz-demo-card-simple',  
    templateUrl: './login.component.html'  
})  
export class LoginComponent implements OnInit {  
    Obj: User;  
    constructor(private srvLogin: AuthService, private router: Router, public activatedRoute: ActivatedRoute, private cookieService: CookieService) {  
        this.Obj = new User();  
    }  
    ngOnInit(): void {}  
    onsubmit(): void {  
        this.cookieService.set('username', this.Obj.username);  
        this.cookieService.set('password', this.Obj.password);  
        console.log(this.cookieService.get('username'));  
        console.log(this.cookieService.get('password'));  
        const a = this.Obj;  
        if (this.srvLogin.checkLogValues(this.Obj)) {  
            this.srvLogin.isloggedin = true;  
            console.log(this.srvLogin.isloggedin);  
            this.router.navigate(['/dashboard']);  
        }  
    }  
}  

The next point is to create an authentication service, we can create a service file by using the syntax.

ng generate service AuthService

The service name which I have given is Authservice and the service will be created and I have provided a default static username and password in service file so that the validation will be executed and redirected to another page (dashboard page) if the user’s credentials are being valid. Open Authservice service.ts file and replace the following code and import it in both service and as well in app-module.ts file.

import {  
    Injectable  
} from '@angular/core';  
import {  
    HttpClient  
} from '@angular/common/http';  
import {  
    CookieService  
} from 'ngx-cookie-service';  
@Injectable({  
    providedIn: 'root'  
})  
export class AuthService {  
    private username = 'vidya';  
    private password = '123456';  
    isloggedin = false;  
    constructor(private http: HttpClient) {}  
    checkLogValues(value: User): boolean {  
        if (this.username === value.username && this.password === value.password) {  
            console.log(this.username);  
            console.log(this.password);  
            // alert('Login valid');  
            return true;  
        } else {  
            alert('please enter valid data');  
            return false;  
        }  
    }  
}  
export class User {  
    username: string;  
    password: string;  
}  

After that create a component named as dashboard and open dashboard.component.html file and replace the following code.

<h3>Hello {{userDisplayName}} you are in Dashboard </h3>  
<div style="text-align:right">  
   <button nz-button nzType="danger" (click)="logout()">Logout</button>  
</div>  

The next step is to open dashboard.component.ts file and replace the following code inside it.

import {  
    Component,  
    OnInit  
} from '@angular/core';  
import {  
    AuthService,  
    User  
} from '../services/authservice.service';  
import {  
    Router,  
    ActivatedRoute  
} from '@angular/router';  
import {  
    CookieService  
} from 'ngx-cookie-service';  
@Component({  
    selector: 'dashboard',  
    templateUrl: './dashboard.component.html'  
})  
export class DashboardComponent implements OnInit {  
    Obj: User;  
    [x: string]: any;  
    userDisplayName = '';  
    password = '';  
    constructor(private srvLogin: AuthService, private router: Router, public activatedRoute: ActivatedRoute, private cookieService: CookieService) {  
        this.Obj = new User();  
        this.userDisplayName = this.cookieService.get('username');  
        this.password = this.cookieService.get('password');  
        this.Obj.username = this.userDisplayName;  
        this.Obj.password = this.password;  
        if (!srvLogin.checkLogValues(this.Obj)) {  
            router.navigate(['/login']);  
        }  
    }  
    ngOnInit(): void {}  
    logout(): void {  
        this.router.navigate(['/login']);  
        this.cookieService.deleteAll();  
    }  
}  

The following next step is to log in to the dashboard by providing the user’s credentials and after the valid login, we can see the user’s name in dashboard as a welcome note by using the user’s login name. So, after entering into the dashboard page open the developer’s tool in the browser and navigate -> Application and select cookies from storage. So, on that, we can see the user name and password have been stored in the cookie table.

So  far we have seen about storing the user’s details in the cookie table and now we can take an overview on clearing the cookies in the cookie table; for that use deleteall() method for clearing the cookies table if  the user is about to click-> logout button.

Conclusion

In this post, we have seen about using cookies in Angular for storing user’s credentials. I hope this article will be useful for you.

Angular Tutorial - Learn Angular from Scratch

Angular Tutorial - Learn Angular from Scratch

Angular Tutorial - Learn Angular from Scratch: This course is for beginners who are curious on how to get started with Angular. In this course you will learn how to download, install and play around with Angular. We teach you the main components of Angular, so that you can get up and running with it asap. You will learn now to start building applications with Angular.

This course is for beginners who are curious on how to get started with Angular. In this course you will learn how to download, install and play around with Angular. We teach you the main components of Angular, so that you can get up and running with it asap. You will learn now to start building applications with Angular.

Learning Angular can be a daunting experience that's why this course was created; to give you an easier learning experience with it.

What am I going to get from this course?

  • You will learn the mayor fundamentals of Angular
  • You will learn how to get up and running with Angular
  • You will learn to create Applications using Angular 5 and beyond

What you'll learn

  • You will learn the mayor fundamentals of Angular
  • You will learn how to get up and running with Angular
  • You will learn to create Applications using Angular 5 and beyond

An Angular Roadmap — The Past, Present, and Future of Angular

An Angular Roadmap — The Past, Present, and Future of Angular

✅Interested in being an Angular developer in 2019? ... blog post it's most likely that you've written some code in javaScript in the past.

Paleolithic JavaScript — SproutCore

In the beginning, there was SproutCore. It was the first comprehensive JavaScript framework aimed at making it easy to build desktop-quality single-page web apps. It’s not that this wasn’t possible before. When Google released Gmail, it showed the world that web apps really could replace complex desktop applications. Google even open-sourced the Closure toolkit — a set of libraries and an optimizing compiler that it used to build Gmail.

The problem was that Google’s Closure tools weren’t very developer-friendly. They relied heavily on Java, which alienated web developers who were used to working with JavaScript, PHP, Ruby, and Python. Gmail was a great demonstration of what was possible, but developing similar applications still felt out of reach for many.

Some courageous developers managed to string together amazing single page apps using a combination of jQuery, duct tape, and hope. While these apps looked amazing to end-users, for the developers working on them, the apps quickly turned into hulking piles of technical debt that made the dev team dread heading to work in the morning.

As a result, a few enterprising developers began to work on frameworks that would bring Gmail-like apps within easy reach of web developers everywhere. SproutCore was the first of these frameworks to take off. It came with a complete set of widgets that made it possible to build complex web applications without even touching HTML or CSS.

This ended up being great for former desktop developers who had been dragged kicking and screaming onto the web. Several more frameworks popped up with similar goals; GWT and Cappuccino were the most prominent. These frameworks even avoided JavaScript by transpiling other languages into JS. Again, this was great for desktop developers. But it left passionate web developers out in the cold and made them feel as though their hard-won HTML, CSS, and JavaScript skills weren’t valuable.

This left an opening for a framework that truly embraced the web, instead of trying to plaster over it and pretend it was something else. A couple of early frameworks (Backbone and Knockout) appeared, and achieved a moderate amount of success. Ember also showed up around this time. It took SproutCore, stripped it down to its bones, and tried to rebuild it into something truly web-friendly. Ember wanted to be the Six Million Dollar Man of the JavaScript world: rebuilt better, stronger, and faster.

None of these frameworks rocketed to popularity. The world was waiting for something better. In 2010, that something better appeared — it was named Angular.

The Golden Age of Angular

Even before Angular version 1.0 had been released, Angular took the front-end development world by storm. Finally, we had an easy-to-use JavaScript framework that treated HTML as a first-class citizen. Developers and designers could now work together to build amazing single-page applications. This came as a relief to designers, who had been annoyed and offended because older frameworks had treated HTML and CSS as tools for barbarians, tools that no civilized developer should have to touch.

The first thing that seemed magical to developers trying Angular for the first time was two-way data binding. Prior to this, most developers had only seen this kind of data binding in desktop frameworks like WPF and Windows Forms. It was great to be able to bind forms and other UI elements to JavaScript model objects. While two-way data binding could cause performance problems when overused, teams that used it judiciously found that Angular enabled them to create complex front-end applications much more quickly than ever before.

Angular proved to be popular for more than just easy binding of data to HTML elements. Angular directives provided an easy way to create reusable HTML + CSS components. Although other JavaScript frameworks provided this before Angular, Angular was the first one that became extremely popular. Reusable components had long been in-use in server-side frameworks. ASP.NET user controls and partial templates in Rails and Django are but a few examples.

Finally, Angular made dependency injection popular in the front-end development world. Dependency injection had long been popular in enterprise applications, which is perhaps why it hadn’t caught on in the JavaScript world. Front-end developers have long been averse to what they see as needlessly complex enterprise software design patterns. This concern isn’t without merit. Have you ever, in the course of writing an application, said to yourself “What I really need here is a “SimpleBeanFactoryAwareAspectInstanceFactory?”

Dependency injection, though, has proven its worth. And Angular made dependency injection easy to use for an audience that hadn’t used it much in the past. Need an HTTP client? Or perhaps you’d like to do some animation? No problem. Angular had built-in services for those. Just ask for them, and Angular would inject them into your components. No need to instantiate anything yourself.

Or perhaps you wanted to use the browser’s window or location objects without making it impossible to unit test your components outside of a browser? Angular had you covered there too, with its built-in $window and $location services. At runtime, you’d get the browser objects you were expecting. And when running unit tests server-side in Node.js, you could pass mock services into your components to ensure they behaved as expected in various scenarios.

If all of this wasn’t enough, Angular also made it simple to register and inject your own services. For developers who were used to binding all their data to the DOM and hoping for the best, this was awesome. If you were writing a new front-end app that called for APIs that would cost your company a lot of money if overused, you’d probably prefer to be able to write tests ahead of time to ensure that your application doesn’t try to do something like calling the Twilio API 800 million times.

So you’d create a Twilio service that gets injected at runtime. At testing time, you’d create a mock service that records the cost of every API call your application is trying to make. You’d write tests that cover common usage scenarios and ensure that these scenarios don’t result in your company receiving a 7-figure bill. Overall, most developers found that Angular directives combined with dependency injection made it possible to write modular, testable front-end applications using tried-and-true software engineering techniques. Many development teams decided that this resulted in a happy state of affairs, and decided to go all-in on Angular.

The Angular Decline? The Rise of React

While things were mostly great in the world of Angular, it wasn’t all sunshine and lollipops. Developers were starting to run into severe performance problems when they tried to bind too many model objects to too many DOM elements. Some applications slowed to a crawl. Direct calls to $digest and other black-magic sorcery started becoming necessary to achieve acceptable performance. Around the same time, a new challenger appeared: React. At first, React didn’t seem to pose too large a danger to Angular. After all, these React weirdos had gone to the trouble of inventing JSX, which looked a lot like a way to mix markup into your code. Hadn’t we gone to a lot of trouble to invent templating languages for the explicit reason of avoiding mixing markup and code?

As it turned out, React’s approach was pretty popular in the front-end development community. It didn’t rocket to popularity, however. Angular was still dominant, and it looked like it would remain that way. Until that is, Angular’s popularity was given a good kick in the teeth from an unexpected source: the Angular team itself.

The Introduction of Angular 2

Angular 2 was first announced at the ng-europe conference in 2014. The Angular team’s plans came as a shock to the Angular community, to say the least. Reaction from Angular developers was swift and negative… and not without reason. Angular 2 would be getting rid of many familiar concepts from Angular 1, introducing a new, incompatible templating language (and oh, by the way) would also be programmed using an entirely new language.

AngularJS

Although both Angular 1 and Angular 2 were called ‘Angular,’ in reality, they were very different frameworks with a few things in common. To help prevent confusion, the Angular team started referring to the old version of Angular as ‘AngularJS’, and the new version as simply ‘Angular.’ This makes intuitive sense since AngularJS was written in JavaScript, and Angular was not. To keep the distinction between the frameworks clear, I’ll be referring to Angular 1 as AngularJS from this point forward.

As a result of all of this, AngularJS developers lost faith in the framework’s future. They threatened to move to a new framework on future projects, and that is precisely what many of them did. React was the biggest beneficiary of the mass exodus from AngularJS.

Although React didn’t do as much as AngularJS, in a way that was positive. If you’re using a view library that doesn’t try to include everything plus the kitchen sink, it’s a lot more difficult for the developers of that library to pull the rug out from under you in the future. In the beginning, using React was a bit of a pain compared to AngularJS. You had to cobble together a patchwork of libraries just to cover the functionality the AngularJS provided out of the box.

Many teams saw this as a good way to reduce risk, because it was unlikely that the developers of all of those libraries would decide to make backward incompatible breaking changes at the same time, which is essentially what Angular had done.

The Emergence of Vue

To compound AngularJS’ woes, another framework named Vue showed up at about the same time the drama over Angular 2 was occurring. Vue was inspired by AngularJS but aimed to simplify it and get rid of what Vue’s creator saw as unnecessary complexity (so Vue felt very familiar to existing AngularJS developers). Vue provided a safe haven for many AngularJS developers who didn’t want to move over to React.

This doesn’t mean that AngularJS developers were not waiting patiently for Angular 2 to appear. But it’s clear that there was a mass exodus from AngularJS to React and Vue due to the uncertainty caused by the plans for Angular 2.

Rising From the Ashes with Angular 2

Eventually, Angular 2 was released. As expected, it did away with many familiar concepts from AngularJS but kept a few of the best pieces like services and dependency injection. Fortunately for the sanity of developers, Angular uses plain TypeScript and not a fork as originally planned.

To make things more confusing, the Angular team maintained a fork of the new framework that used the Dart programming language instead of TypeScript. Initially, the TypeScript and Dart versions were developed in sync, generated from a single code base. Eventually, the TS and Dart versions of Angular decided to go their separate ways, and Angular Dart now exists on its own.

Even with this confusion, Angular’s popularity began to increase again after the Angular 2 release. It happened slowly. As often occurs in software development, trends shifted. Developers realized that a big, batteries-included framework might actually be useful. After all, when your application grows large enough, you end up actually needing all of those batteries.

Enterprise developers, in particular, began moving back to Angular. This makes sense. Usually, when you start an enterprise web app, you know it is going to be complex. There’s no point in starting with a tiny MVP when you know from the beginning all 87 things your application is going to be expected to do.

Where’s Angular 3?

Although Angular 2 wasn’t perfect, many developers of complex web applications began to realize that the new-and-improved Angular was a good fit for their needs. Fortunately for them, Angular had some exciting improvements in store. More importantly, the Angular team demonstrated that it could consistently publish new versions of the framework with few breaking changes between versions

In a move that seemed odd at the time, the Angular team decided to skip version 3 entirely and move to version 4. This was done for good reason: the team working on Angular’s router package had already pushed ahead and released version 3, while the remainder of Angular was still at version 2.3. They decided to keep all Angular package versions in sync moving forward, and bumping everything up to version 4 for the next release was the easiest way to achieve this.

Angular 4

Angular 4 had some significant changes, including added ahead of time compilation, which resulted in small production JavaScript bundles and shorter application load time. Support for server-side rendering was added, which was a boost for teams that wanted to render their app ahead of time to improve initial load performance. Many other improvements were added throughout the framework, but upgrading apps from Angular 2 to 4 was quick and painless in most cases.

Angular 4.3 and Angular 5

Angular 4.3 added a new HTTP client that was easier to use than the old HTTP service. In Angular 5, the old HTTP service was deprecated and would be dropped in the next release. In spite of this inconvenience, there was relatively little grumbling because the upgrade in most cases was straightforward. Angular 5 also added better internationalization support and further build optimizations.

Angular 6 and 7

Angular 6 and 7 were disappointing to some developers. There were no large changes, but there were many small quality of life improvements, especially to the Angular CLI tooling. The decreasing number of visible changes isn’t an indication that the Angular team has stopped innovating. Instead, it shows that the framework is mature, so the development team is now free to do more work behind the scenes, fixing bugs and improving performance.

The stability of the framework since the release of Angular 2 has drawn some old-school AngularJS developers back into the Angular world. It has also attracted the attention of enterprise development teams. When you’re building enterprise apps that may live for decades it’s ideal to use a framework that gets new releases on a predictable schedule but doesn’t change too rapidly. A developer who had only used Angular 2 could be up and running and contributing to an Angular 7 app within minutes.

The Future of Angular

Angular 8 and Angular Ivy

And that brings us to today. As we’ve seen, Angular has come a long way. It has gone from loved by web developers to being reviled to being admired, although it isn’t yet loved again like it was in its early days.

On the horizon, we have Angular 8. A ton of work has been done in Angular 8 to make it easy to use with the Bazel build system, which is absolutely amazing news for all 3 developers who are using it outside of Google. More excitingly, though, the Angular team is hard at work on a new rendered called Angular Ivy. It’s intended to be a drop-in replacement for the current rendered. For the most part, current apps won’t need to make any changes to use Angular Ivy.

If Angular Ivy is a drop-in replacement, why should developers care? Two important reasons: speed, and bundle size — two very important concerns. For a few years, it seemed like web developers had gone a bit crazy. Teams were shipping JavaScript bundles that were 5MB, 10MB, or even larger, and thinking that there was no problem with this. After all, the applications worked perfectly on the developers’ i7-powered MacBook Pros so they should work fine for everyone, right?

Unfortunately, in the real world, not everyone is running the latest and greatest hardware. Hundreds of millions of people access the internet solely on older Android phones with slightly more processing power than a potato, through internet connections only a little faster than dial-up. For these users, a huge JavaScript bundle takes forever to load, and even longer for their device to parse and run. Even in less extreme cases, there are countless users around the world who aren’t using the latest and greatest hardware. For them, massive JavaScript apps are usable (but painful).

Angular Ivy Expectations

The Angular Ivy renderer will help in several ways:

  1. It is being written with an eye on efficiency, so it will accomplish the same tasks while executing far fewer CPU instructions. This will improve both the battery life and the sanity of users with less-than-powerful devices.
  2. The renderer will be written in a much more modular fashion that the current renderer. This will make it much more amenable to tree-shaking and dead code elimination. As a result, your production JavaScript bundle will include only the code that is needed to run your application, instead of bundling together everything plus the kitchen sink as often happens with the current rendered.
  3. In addition to the bundle-size reduction and improved rendering speed, Angular Ivy has another few quality-of-life enhancements for Angular developers. Rebuild times are significantly faster. So if you’re running your app in development mode and waiting for your changes to appear, you’re now going to be spending a lot less time waiting.
  4. Template-type checking is improved, which means you’ll catch more errors at compile time instead of at runtime. Runtime template bugs are annoying, because they either bite you during testing, or they bite your users when they’re trying to use your app.
  5. The Angular Ivy template compiler will generate code that is human readable, which the current View Engine compiler doesn’t do. This will come in handy when trying to track down tough template bugs.

The net result: smaller apps, faster apps, happier developers, and happier users.

Angular’s Past, Present, and Future

If you’ve been using Angular from its early days all the way until now, then congratulations! While there have been plenty of rough patches, we’ve ended up with a fast, modern framework that is fun to use.

If you were an AngularJS developer but moved on to React, Vue, or something else, I encourage you to give Angular another look. It’s worth your time, even if you decide to stick with what you’re using now.

And if you’ve never used Angular at all, why not give it a shot?

We’ve just been on a whirlwind tour through Angular’s past, present, and future. Without a doubt, it has been quite a ride. Regardless of your Angular background, I hope you’ve enjoyed the tour!

30s ad

Angular 2 Firebase - Build a Web App with Typescript

Angular 2 Demystified

Master Angular 2 - The No Nonsense Course

Complete Angular 7 - Ultimate Guide - with Real World App

A Quick Guide to Angular 7 in 4 Hours