Introduction to Angular

What is Angular

Angular is a JavaScript-based front-end web application framework, maintained by google, that aims to change the way single-page applications are developed through component-based coding.

Advantages of Templating in Angular

Templates (for the most part) have a one to one relationship with components in Angular. Components must have a view, so you use a template (you can define this template in an inline manner or in a separate file.)

Basically, a template is what we use to help render HTML with dynamic parts. Templates give us the ability to express data through the binding of properties, and events. To do this, Angular 2 comes with some key symbols the author can use to express certain behaviors:

Data Binding

  • {{ }} for Interpolation.
  • [ ] for Property Binding.
  • ( ) for Event Binding.
  • # for Variable Declaration.
  • * for Structural Directives.

Data binding is Angular’s way of synchronizing data between the model and the view.

In Angular, there are multiple ways to bind data: interpolation, one way binding (unidirectional), two-way binding, and event binding. Interpolation is the easiest and best-known way. The biggest reason for this is to keep the front and backend synced.


<table class="table table-bordered table-responsive table-striped table-word-wrap">
	<tr>
		<th>Misquote ID</th>
		<th>Misquote</th>
		<th>Attribution</th>
		<th>Submitter</th>
		<th>Edit</th>
	</tr>
	<tr *ngFor="let misquote of misquotes">
		<td> { { misquote.misquoteId } } </td>
		<td> { { misquote.misquote } } </td>
		<td> { { misquote.attribution } }</td>
		<td> { {  misquote.submitter } }</td>
		<td><a class="btn btn-warning" (click)="switchMisquote(misquote);"><i class="fa fa-pencil" aria-hidden="true"></i></a>
		</td>
	</tr>
</table>
Disclaimer: there should be no spaces between the curly brackets

Angular !== Angularjs

Angular is not a newly released version of Angularjs, it’s a complete rewrite. There are tons of new features, and some old things that have been moved over to Angular.

While some of the functionality did move over, the syntax did not. Angular has made the syntax easier to use, and more logical for the writer.

Angular Component-Template Architecture

Keys to Angular Architecture

TypeScript

Typescript is strongly typed superset of JavaScript that compiles into plain JavaScript. It starts from the same syntax that JavaScript developers know, but adds helpful features that make coding easier, such as type checking and object oriented features. For more information about typescript syntax take a look at the Typescript handbook

JavaScript


var Todo = (function () {
	function Todo(todoId, todoText) {
		this.todoId = todoId;
		this.todoText = todoText;
	}
	Todo.prototype.getTodoId = function () {
		return (this.todoId);
	};
	Todo.prototype.setTodoId = function (newTodoId) {
		this.todoId = newTodoId;
	};
	Todo.prototype.getTodoText = function () {
		return (this.todoText);
	};
	Todo.prototype.setTodoText = function (newTodoText) {
		this.todoText = newTodoText;
	};
	return Todo;
}());

TypeScript


class Todo {
	constructor(private todoId: number, private todoText: string) {}

	getTodoId() : number {
		return(this.todoId);
	}

	setTodoId(newTodoId: number) {
		this.todoId = newTodoId;
	}

	getTodoText() : string {
		return(this.todoText);
	}

	setTodoText(newTodoText: string) {
		this.todoText = newTodoText;
	}
}

Observables

Observables are used extensively in Angular, and are very similar to Promises but with some key differences. Observables and Promises are both used to perform the very important web application operation of posting and getting data from a server.

In Angular, Observables are used for triggering events and obtaining new data. The reason Observables won out over Promises in Angular 2 is because it provides more features than Promises, and is much more flexible.

For example, it doesn’t matter if you want to handle a 0, 1, or multiple events - an Observable can use the same API for each case. A Promise will only return a single value.

Services

An Angular service is used to share functionality of your application through components.

Because services can be shared between any number of components, it’s the best way to bring data to our application or to do repetitive tasks and keep your code DRY.

import {HttpClient} from "@angular/common/http";
import {Injectable} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {Misquote} from "../classes/misquote";
import {Status} from "../classes/status";

@Injectable()
export class MisquoteService {

	constructor(protected http: HttpClient) {}

	private misquoteUrl = "api/misquote/";

	//grab a misquote object by its primary key
	getMisquote(misquoteId: string) : Observable<Misquote> {
		return(this.http.get<Misquote>(this.misquoteUrl + misquoteId));
	}

}

HTTP Interceptor

Http Interceptors are a new feature in Angular that was introduced in Angular 4.3. Interceptors are powerful tools that mutate or change incoming and outgoing HTTP calls. Interceptors accomplish this by sitting between the Service and the HTTP protocol and modifying the stream that observables (in the services) interact with.

import {Injectable} from "@angular/core";
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from "@angular/common/http";
import {Observable} from "rxjs/Observable";

/**
 * class that intercepts data for Deep Dive's API standard
 *
 * All APIs in Deep Dive return an object with three state variables:
 *
 * 1. status (int, required): 200 if successful, any other integer if not
 * 2. data (any, optional): result of a GET request
 * 3. message (string, optional): status message result of a non GET request
 *
 * this interceptor will use the HttpResponse to return either the data or the status message
 **/
@Injectable()
export class DeepDiveInterceptor implements HttpInterceptor {

	/**
	 * intercept method that extracts the data or status message based on standards outlined above
	 *
	 * @param {HttpRequest<any>} request incoming HTTP request
	 * @param {HttpHandler} next outgoing handler for next interceptor
	 * @returns {Observable<HttpEvent<any>>} Observable for next interceptor to subscribe to
	 **/
	intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
		// hand off to the next interceptor
		return(next.handle(request).map((event: HttpEvent<any>) => {
			// if this is an HTTP Response, from Angular...
			if(event instanceof HttpResponse) {
				// create an event to return (by default, return the same event)
				let dataEvent = event;

				// if the API is successful...
				if(event.status === 200) {

					// extract the data or message from the response body
					let body = event.body;
					if(body.status === 200) {
						if(body.data) {
							// extract data returned from a GET request
							dataEvent = event.clone({body: body.data});
						} else if(body.message) {
							// extract a successful message
							dataEvent = event.clone({body: {message: body.message, status: 200, type: "alert-success"}});
						}
					} else {
						// extract a failing message when the API fails
						dataEvent = event.clone({body: {message: body.message, status: body.status, type: "alert-danger"}});
					}
				} else {
					// extract a failing message when the web server fails
					dataEvent = event.clone({body: {message: event.statusText, status: event.status, type: "alert-danger"}});
				}
				return(dataEvent);
			}
		}));
	}
}

Components

In Angularjs, to build and specify elements, you had to use directives, controllers, and scope. Angular simplified this and made it all achievable through a component. Components can also inherit, and take advantage of Angular's enhanced dependency injection.

import {Component, OnInit} from "@angular/core";
import {ActivatedRoute} from "@angular/router";
import {MisquoteService} from "../services/misquote.service";
import {Misquote} from "../classes/misquote";
import {Status} from "../classes/status";

@Component({
	//url of the template for this component
	template: require("./misquote.html")
})

// export the component - Allows the Component to be imported into different files in the project.
// This also lets us define variables or functions that the template will use.
export class MisquoteComponent implements OnInit {
	misquote: Misquote = new Misquote(null,null,null,null);


	// This is where the dependencies are called.
	constructor(private misquoteService: MisquoteService, private route: ActivatedRoute) {
	}

	// This will load the content as soon as the page is ready.
	ngOnInit(): void {
		this.getMisquoteById();
	}

	getMisquoteById() : void {
		// grab the misquoteId from the Url
		let misquoteId : string  = this.route.snapshot.params["misquoteId"];

		// use the misquote service  to grab a misquote from the server
		this.misquoteService.getMisquote(misquoteId)
			.subscribe(misquote => this.misquote = misquote);
	}
}

Routes

Routes are an array that navigates to certain parts of the app. Each route is used to map a URL path to a component. When the user navigates to ‘foo’ path, it will load the component, which in turn loads the view template for the user.

export const allAppComponents = [MisquoteComponent, MisquoteListComponent, SplashComponent];

export const routes: Routes = [
	{path: "misquote", component: MisquoteListComponent},
	{path: "misquote/:misquoteId", component: MisquoteComponent},
	{path: "", component: SplashComponent}
];

Modularity

A modular system is great for building large web applications because it makes your app easier to understand, maintain, and extend by separation of concerns into independent pieces, or 'modules'.

@NgModule({
	imports:      [BrowserModule, FormsModule, HttpModule, routing],
	declarations: [...moduleDeclarations, ...allAppComponents],
	bootstrap:    [AppComponent],
	providers:    [appRoutingProviders, MisquoteService]
})
export class AppModule {}