text:
# Angular

Get started with and understand the basics of [Angular][angular], the JavaScript front-end web application framework.

This tutorial is a condensed version of Angular's [Tour of Heroes][angular-tour-of-heroes] tutorial and some of its [Developer Guide][angular-guide],
which you should both read to gain a deeper understanding of Angular.

**You will need**

* [Google Chrome][chrome] (recommended, any browser with developer tools will do)

**Recommended reading**

* [JavaScript][js]
* [JavaScript classes][js-classes]
* [JavaScript modules][js-modules]
* [TypeScript][ts-subject]

- [What is Angular?](#what-is-angular)
  - [Traditional Model-View-Controller (MVC) architecture](#traditional-model-view-controller-mvc-architecture)
  - [DOM manipulation and AJAX requests](#dom-manipulation-and-ajax-requests)
  - [Single-page applications](#single-page-applications)
  - [Dynamic HTML with Angular](#dynamic-html-with-angular)
  - [Evolution of Angular](#evolution-of-angular)
- [Getting started](#getting-started)
  - [Starter template](#starter-template)
  - [Overview](#overview)
  - [Modules](#modules)
  - [Components](#components)
  - [Data binding](#data-binding)
- [User input](#user-input)
  - [`ngModel`](#ngmodel)
  - [Two-way data binding](#two-way-data-binding)
- [Directives](#directives)
  - [Structural directives](#structural-directives)
  - [Attribute directives](#attribute-directives)
  - [Common directives](#common-directives)
- [Models](#models)
  - [Using models](#using-models)
  - [Using `ngFor`](#using-ngfor)
  - [Using `ngPlural`](#using-ngplural)
- [Pipes](#pipes)
  - [Implementing a pipe](#implementing-a-pipe)
  - [Using a pipe](#using-a-pipe)
  - [Pipe parameters](#pipe-parameters)
  - [Angular built-in pipes](#angular-built-in-pipes)
- [Services](#services)
  - [The joke service](#the-joke-service)
  - [Providing the joke service](#providing-the-joke-service)
  - [Injecting the joke service](#injecting-the-joke-service)
  - [Why does it work?](#why-does-it-work)
  - [Dependency injection](#dependency-injection)
- [Observable data](#observable-data)
  - [What (the hell) is an observable?](#what-the-hell-is-an-observable)
  - [What (the hell) is reactive programming?](#what-the-hell-is-reactive-programming)
  - [Making `getJoke()` observable](#making-getjoke-observable)
  - [Subscribing to an Observable](#subscribing-to-an-observable)
- [Making HTTP calls](#making-http-calls)
  - [Injecting `HttpClient`](#injecting-httpclient)
  - [Joke API response](#joke-api-response)
  - [Making a GET call](#making-a-get-call)
  - [Transforming data](#transforming-data)
  - [Transforming Observable streams](#transforming-observable-streams)
  - [Reacting to errors in observable streams](#reacting-to-errors-in-observable-streams)
  - [Getting the HTTP response](#getting-the-http-response)
- [Component interaction](#component-interaction)
  - [Adding votes to the model](#adding-votes-to-the-model)
  - [Creating a child component](#creating-a-child-component)
  - [Passing data from parent to child with input binding](#passing-data-from-parent-to-child-with-input-binding)
  - [Voting on jokes](#voting-on-jokes)
  - [Displaying global voting information](#displaying-global-voting-information)
  - [Output from child components](#output-from-child-components)
  - [Listening to child component events from a parent](#listening-to-child-component-events-from-a-parent)
  - [Clearing the votes](#clearing-the-votes)
  - [More component interaction](#more-component-interaction)
- [Forms](#forms)
  - [HTML validations](#html-validations)
  - [Creating a form](#creating-a-form)
  - [Checking the validation state](#checking-the-validation-state)
  - [Angular validators](#angular-validators)
  - [Custom validators](#custom-validators)
  - [Displaying different messages for different errors](#displaying-different-messages-for-different-errors)
  - [Asynchronous validators](#asynchronous-validators)
- [Reactive forms](#reactive-forms)
  - [Using reactive forms in the component](#using-reactive-forms-in-the-component)
  - [Using reactive forms in the template](#using-reactive-forms-in-the-template)
  - [Reactive form validations](#reactive-form-validations)
  - [Which is better, reactive or template-driven?](#which-is-better-reactive-or-template-driven)
- [Resources](#resources)

## What is Angular?

> "Angular is a complete **JavaScript front-end web application framework** created by Google to address many of the challenges of developing **rich single-page applications**."

### Traditional Model-View-Controller (MVC) architecture

In traditional MVC frameworks,
the application's **Controllers** receive the user's requests when navigating from page to page in the browser,
and respond by generating HTML **Views** from the **Model**.

### DOM manipulation and AJAX requests

Serving dynamic HTML from the server works, but each user action requires that a **complete page be loaded** from the server.

To improve user experience:

* [AJAX][ajax] was developed in 1999 to retrieve data from the server asynchronously in the background
* [jQuery][jquery] was released in 2006 to simplify DOM manipulation and AJAX requests

This allows you to load data from the server in the background and **dynamically update the page** without reloading.

Initially, these technologies were used to **enrich** existing HTML pages that were still built and served by a traditional MVC framework.

### Single-page applications

A single-page application (SPA) is a web application that **fits on a single web page** but provides a user experience similar to that of a **desktop application**:

* All content is retrieved with a **single page load or loaded dynamically**
* The page **does not reload** (location hash or [HTML 5 History API][html-history-api] to navigate between logical pages)
* Dynamic **communication with the web server** behind the scenes

### Dynamic HTML with Angular

> "AngularJS is what HTML would have been, had it been designed for building web-apps."

HTML is great for displaying static documents, but is not so good at describing the **dynamic views** needed for **rich, interactive applications**.

With Angular, you can:
  * **Automatically bind data** to HTML elements
  * **Extend the HTML vocabulary** with new elements and attributes
  * **Isolate** your application logic from how the data is displayed

### Evolution of Angular

Angular is one of the most popular client-side frameworks, and it is still evolving.
Starting with version 2 of the framework (released in June 2016) you can take advantage of:

* [TypeScript][ts]: a superset of JavaScript with optional typing and the latest ECMAScript features
* [Web components][web-components]: a way to create reusable user interface widgets
* And more...

## Getting started

### Starter template

You can clone the following project for the exercises in this tutorial:

[COMEM+ Angular Starter Project][angular-starter]

You should keep your [developer console][chrome-dev] open throughout this tutorial to detect errors in your code.

### Overview

**Angular elements**

* Modules
* Components
* Directives
* Services
* HTTP
* Pipes

**Angular concepts**

* Interpolation
* Data binding
* Dependency injection
* Observables & reactive programming
* Form validation

### Modules

An Angular application is a **module**.
You can find one in `src/app/app.module.ts` in the starter project:

```ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

`@NgModule`({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export `class AppModule` { }
```

A module is a way to help organize related things (components, services, etc) together.

#### Basic module definition

Take a look at the [`@NgModule`][angular-docs-ng-module] annotation:

```ts
@NgModule({
  `declarations`: [
    AppComponent
  ],
  `imports`: [
    BrowserModule
  ],
  `providers`: [],
  `bootstrap`: [AppComponent]
})
```

* The **declarations** array is a list of components (also directives and pipes) which belong to this module.
* The **imports** array is a list of other modules whose exported components should be available in this module.
  It allows you to express a dependency on another module.
* The **providers** array is a list of service providers (more about that later).
* **bootstrap** is the root component that Angular creates and inserts into `index.html`

### Components

Components are the most basic **building block** of an UI in an Angular application.
An Angular application is a tree of Angular components.

You will find a component in `src/app/app.component.ts` in the starter project:

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

`@Component`({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export `class AppComponent` {
  title: string;

  constructor() {
    this.title = 'app';
  }
}
```

A component is any [JavaScript class][js-classes] annotated with the [`@Component`][angular-docs-component] decorator.

Let's dig into that line by line.

#### Component selector

The `selector` property of the `@Component` decorator indicates what tag you should put in your HTML to instantiate the component:

```ts
@Component({
  `selector: 'app-root'`,
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
```

Open `src/index.html` in the starter project.
You will find the `<app-root>` tag:

```html
<body>
  `<app-root></app-root>`
</body>
```

#### Component template

The `templateUrl` property of the `@Component` decorator tells Angular which HTML file to use to display the component:

```ts
@Component({
  selector: 'app-root',
  `templateUrl: './app.component.html'`,
  styleUrls: ['./app.component.css']
})
```

For very simple components, you can also use `template` instead of `templateUrl` to use an **inline template**:

```ts
@Component({
  selector: 'app-root',
  `template: '<h1>Welcome to {{ title }}!</h1>'`,
  styleUrls: ['./app.component.css']
})
```

#### Component styles

Similarly, the `styleUrls` property is a list of CSS files to apply to the component:

```ts
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  `styleUrls: ['./app.component.css']`
})
```

It's also possible to use **inline styles** for very simple components:

```ts
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  `styles: [ 'h1 { font-weight: normal;  }' ]`
})
```

Styles in Angular are **modular**.
They apply only *within the template of that component*.

Read the [Component Styles][angular-component-styles] documentation to learn more.

### Data binding

You can display data by **binding** parts of an HTML template to properties of a component.
There is already a `title` property in `AppComponent` in `src/app/app.component.ts`:

```ts
export class AppComponent {
  `title: string;`

  constructor() {
    this.title = 'app';
  }
}
```

Enclosing a component's property name in double curly braces in the template is called **interpolation**.
This is already done in the `AppComponent`'s template in `src/app/app.component.html`:

```html
<h1>
  Welcome to `{{ title }}`!
</h1>
```

#### Attribute binding

Let's see what else we can interpolate.
Add a `titleComment` property to the component in `src/app/app.component.ts`:

```ts
export class AppComponent {
  title: string;
  `titleComment: string;`

  constructor() {
    this.title = 'app';
    `this.titleComment = 'This is awesome!';`
  }
}
```

Angular's `[]` syntax allows you to bind the value of a DOM element's **attribute** to one of the component's variables.
You can do this in `src/app/app.component.html`:

```html
<h1 `[title]='titleComment'`>
  Welcome to {{ title }}!
</h1>
```

##### To bind, or not to bind

Note the two ways to interpolate attributes.
Here, as in the previous example, the `[]` syntax **binds the the `title` attribute** to the `titleComment` variable:

```html
<h1 `[title]='titleComment'`>
  Welcome to {{ title }}!
</h1>
```

Here, the `title` attribute itself is not bound, but its **value is interpolated** with the `{{  }}` syntax.
The behavior will be the same as the previous example:

```html
<h1 title='`{{ titleComment }}`'>
  Welcome to {{ title }}!
</h1>
```

Here, we made a **mistake**.
We neither bound the attribute, nor used interpolation in its value,
so the value of the attribute will be the string `"titleComment"`,
not the value of the corresponding variable:

```html
<h1 title='titleComment'>
  Welcome to {{ title }}!
</h1>
```

#### Binding to events

Let's imagine that we want to log something when the user clicks on the title.
Add an `onTitleClicked()` function to the component in `src/app/app.component.ts`:

```ts
export class AppComponent {
  // ...

* onTitleClicked() {
*   console.log('The title was clicked');
* }
}
```

Angular's `()` syntax allows you to **bind functions to events** from a DOM element.
Let's bind the function we just added to click events on the `<h1>` tag in `src/app/app.component.html`:

```html
<h1 [title]='titleComment' `(click)='onTitleClicked()'`>
  Welcome to {{ title }}!
</h1>
```

You should now see the message being logged in the console when clicking on the title.

##### Getting at the event

You might need the actual [event object][dom-event] to get some data out of it (e.g. the click coordinates).
Let's update `onTitleClicked()` in `src/app/app.component.ts` to also log the event object:

```ts
export class AppComponent {
  // ...

  onTitleClicked(`event`) {
    console.log('The title was clicked'`, event`);
  }
}
```

To make it work, simply add the special `$event` variable to your function call in `src/app/app.component.html`,
and Angular will pass the event object to your function:

```html
<h1 [title]='titleComment' (click)='onTitleClicked(`$event`)'>
  Welcome to {{ title }}!
</h1>
```

#### Interpolation with functions

Interpolation is not limited to simple properties.
You can also use a component's **methods** in the template.

Add the following method to the component in `src/app/app.component.ts`:

```ts
export class AppComponent {
  // ...

* hello(name: string): string {
*   return \`Hello ${name}`;
* }
}
```

Now use that function in the template in `src/app/app.component.html`:

```html
<p>
  `{{ hello("World") }}`
</p>
```

## User input

One of the things you will need to do is **react to user input** (e.g. through forms).
Let's make our greeting **dynamic** by adding an input field to customize the name.
Make the following changes to the component in `src/app/app.component.ts`:

```ts
export class AppComponent {
  // ...
  `greeting: string;`

  constructor() {
    this.title = 'app';
    `this.greeting = '';`
  }
  // ...
}
```

Now interpolate that new property into the `hello` function in the template in `src/app/app.component.html`:

```html
<p>
  {{ hello(`greeting`) }}
</p>
```

### `ngModel`

Add an input field to the template above the greeting in `src/app/app.component.html`:

```html
*<p>
* <input type='text' placeholder='Who are you?' [(ngModel)]='greeting' />
*</p>
<p>
  {{ hello(greeting) }}
</p>
```

`[(ngModel)]` is Angular's **two-way data binding** syntax.
It binds the `greeting` property to the HTML input field.

You will most likely get this error:

```
Uncaught Error: Template parse errors:
Can't bind to 'ngModel' since it isn't a known property of 'input'.
```

This is because `[(ngModel)]` belongs to the optional `FormsModule`, which you have to *opt in* to using.

#### `FormsModule`

To **import** the module into your application, you must add it to the `imports` array of your own module in `src/app/app.module.ts`:

```ts
// Other imports...
*import { FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    `FormsModule`
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
```

Once you've done that, the field should display correctly.

Note that as you type in the input field, the `greeting` variable is **automatically kept up-to-date**,
and Angular **updates the template** to reflect its new value.

### Two-way data binding

Traditional templating systems bind data **in only one direction**.

The developer has to write code that constantly syncs the view with the model and vice versa.

With Angular changes are **immediately reflected** in both view and model.

Also note that our **component** is **isolated from and unaware of the view**:
it does not care about DOM manipulation or rendering concerns.

## Directives

A **directive** is a class with a `@Directive` decorator.

The **component** that we've seen before is a *directive-with-a-template*.
A `@Component` decorator is actually a `@Directive` decorator extended with template-oriented features.

Two other kinds of directives exist: **structural** and **attribute** directives.

### Structural directives

Structural directives are responsible for HTML layout.
They shape or reshape the **DOM's structure**, typically by **adding, removing, or manipulating elements**.

Let's add the [`ngIf`][angular-docs-ng-if] directive to our template in `src/app/app.component.html` as an example:

```html
<p `*ngIf='greeting'`>
  {{ hello(greeting) }}
</p>
```

As you can see, the entire paragraph is now removed from the DOM as long as the `greeting` property is blank (e.g. `undefined` or an empty string).
It is added back as soon as `greeting` has a value.

Read the [documentation][angular-structural-directives] to learn more about structural directives.
Many more such directives are provided by Angular out of the box, like [`ngFor`][angular-docs-ng-for] (which we'll use later) and [`ngSwitch`][angular-docs-ng-switch].

### Attribute directives

An **attribute** directive changes the **appearance or behavior of a DOM element**.

Create a `src/app/highlight.directive.ts` file with the following contents:

```ts
import { Directive } from '@angular/core';

`@Directive`({
  selector: '[appHighlight]'
})
export `class HighlightDirective` {
  constructor() {
    console.log('the highlight directive was used');
  }
}
```

Similarly to a component, a directive is a JavaScript class, this time annotated with the [`@Directive`][angular-docs-directive] decorator.

The selector, `[appHighlight]` is an [attribute selector][css-attribute-selector].
Also note that it is good practice to prefix the selector with your application name ("app" for this example) to avoid **naming collisions** with other directives.

#### Using an attribute directive

To use your new attribute directive, you must **declare** it in your module's `declarations` array in `src/app/app.module.ts`:

```ts
*import { HighlightDirective } from './highlight.directive';
// Other imports...

@NgModule({
  declarations: [
    AppComponent,
    `HighlightDirective`
  ],
  // ...
})
export class AppModule { }
```

Now all you need to do is add the attribute to an element in `src/app/app.component.html`.
Let's add it to the greeting.

```html
<h1 [title]='titleComment' (click)='onTitleClicked($event)' `appHighlight`>
  Welcome to {{ title }}!
</h1>
```

You should see the directive being used in the console after entering some text in the input field.

#### Modifying the DOM

Now add an `ElementRef` argument to the directive's constructor in `src/app/highlight.directive.ts`:

```ts
import { Directive, `ElementRef` } from '@angular/core';

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(`el: ElementRef`) {
    `el.nativeElement.style.backgroundColor = 'yellow';`
  }
}
```

Doing this **injects** a reference to the host DOM element, the element to which you applied the `appHighlight` attribute.

`ElementRef` grants direct access to the host DOM element through its `nativeElement` property.
In this example we set the background color to yellow.

### Common directives

These common directives are provided by Angular out of the box:

* [`ngClass`][angular-docs-ng-class] - Adds and removes **CSS classes** on an HTML element.
* [`ngFor`][angular-docs-ng-for] - Instantiates a template **once per item** from an iterable.
* [`ngIf`][angular-docs-ng-if] - **Conditionally includes** a template based on the value of an expression.
* [`ngModel`][angular-docs-ng-model] - **Two-way binding** between a form's input field and a component's variable.
* [`ngPlural`][angular-docs-ng-plural] - Adds/removes DOM sub-trees based on a numeric value. (Tailored for **pluralization**.)
* [`ngStyle`][angular-docs-ng-style] - Update an HTML element's **styles**.
* [`ngSwitch`][angular-docs-ng-switch] - Adds/removes DOM sub-trees when the nest match expressions matches the **switch** expression.

## Models

Let's make our application funny by adding some jokes.

It's good practice to create **classes** for your **business models**.
A TypeScript class with clearly defined fields and types will help us avoid mistakes in our code.
Let's start with a very simple one.

Angular CLI comes with scaffolding tools to help you create files.
Install it, then generate a model class
(the second command must be run in the project's directory):

```bash
$> npm install -g @angular/cli
$> ng generate class models/joke
```

This will create a `src/app/models/joke.ts` file.
Open it and add a `text` attribute to our new `Joke` class:

```ts
export class Joke {
  `text: string;`
}
```

### Using models

Let's add some jokes to our component in `src/app/app.component.ts`:

```ts
// Other imports...
`import { Joke } from './models/joke';`

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title: string;
  greeting: string;
  `jokes: Joke[];`

  constructor() {
    this.title = 'app';
    this.greeting = '';
*   this.jokes = [
*     { text: 'Knock knock' },
*     { text: 'The cake is a lie' }
*   ];
  }
  // ...
}
```

### Using `ngFor`

Now that we have some jokes, let's display them.
We want a `<ul>` list, with a `<li>` item for each joke.
That's a job for the [`ngFor`][angular-docs-ng-for] directive.

Add this at the bottom of the component's template in `src/app/app.component.html`:

```html
<ul>
  <li *ngFor='let joke of jokes'>{{ joke.text }}</li>
</ul>
```

The directive handles repeating the `<li>` element for us.
No need to write it multiple times, or to manually build and concatenate DOM elements in the component's TypeScript code.

### Using `ngPlural`

While we're at it, let's also add a header above the list:

```html
<h2>
  {{ jokes.length }} jokes
</h2>
```

You might notice that we'll have a minor problem when there is only one joke.
It will say "1 jokes" instead of "1 joke".

The [`ngPlural`][angular-docs-ng-plural] directive comes to the rescue:

```html
<h2 `[ngPlural]='jokes.length'`>
  {{ jokes.length }}
* <ng-template ngPluralCase='=1'>joke</ng-template>
* <ng-template ngPluralCase='other'>jokes</ng-template>
</h2>
```

## Pipes

When primitive values or objects are interpolated into a template, they are serialized by Angular using their `toString()` method.

That's fine for strings, but not for everything:

* What about **numbers**? You might not want to display all their decimals.
* What about **currencies**? They are usually displayed in a specific format.
* What about **dates**? You might want to use a simple format like `April 15, 1988` rather than the default `Fri Apr 15 1988 00:00:00 GMT-0700 (Pacific Daylight Time)`.

Clearly, some values benefit from a bit of editing.
Pipes allow you to define **reusable value transformations** that you can apply in your HTML templates.

### Implementing a pipe

Let's implement an (amazing) pipe that adds an exclamation point to the end of a string:

```bash
$> ng generate pipe --spec false pipes/exclamation
```

Implement the transformation in the generated file (`src/app/pipes/exclamation.pipe.ts`):

```ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'exclamation'
})
export class ExclamationPipe implements PipeTransform {
  transform(value: any, args?: any): any {
*   return \`${value}!`;
  }
}
```

### Using a pipe

Note that Angular automatically registered our pipe in the module's `declarations` array in `src/app/app.module.ts`.
This is necessary to be able to use it in a template:

```ts
// Other imports...
*import { ExclamationPipe } from './pipes/exclamation.pipe';

@NgModule({
  declarations: [
    AppComponent,
    `ExclamationPipe`
  ],
  // ...
})
export class AppModule { }
```

Using the pipe is as simple as "piping" an interpolated value into it with the pipe (`|`) character in a template.
You can do that in `src/app/app.component.html`, then type some text in the input field to see it:

```html
<p>
  {{ hello(greeting)` | exclamation` }}
</p>
```

### Pipe parameters

Pipe can also take **parameters**.
Let's add a number parameter to allow customizing the number of exclamation points in `src/app/pipes/exclamation.pipe.ts`:

```ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'exclamation'
})
export class ExclamationPipe implements PipeTransform {
  transform(value: any`, strength: number = 1`): any {
*   const exclamation = '!'.repeat(strength);
*   return \`${value}${exclamation}`;
  }
}
```

Parameters are passed to pipes by appending `:value` to them in the template in `src/app/app.component.html`:

```html
<p>
  {{ hello(greeting) | exclamation`:3` }}
</p>
```

### Angular built-in pipes

Angular provides [a few pipes][angular-docs-pipes] out of the box.
Here's some of them:

* [`CurrencyPipe`][angular-docs-currency-pipe]
* [`DatePipe`][angular-docs-date-pipe]
* [`DecimalPipe`][angular-docs-decimal-pipe]
* [`LowerCasePipe`][angular-docs-lowercase-pipe], [`UpperCasePipe`][angular-docs-uppercase-pipe] & [`TitleCasePipe`][angular-docs-titlecase-pipe]
* [`PercentPipe`][angular-docs-percent-pipe]

Here's few usage examples for [`DatePipe`][angular-docs-date-pipe]:

```html
<!-- Output: Jun 15, 2015 -->
<p>Today is {{ dateValue | date }}</p>

<!-- Output: Monday, June 15, 2015 -->
<p>Or if you prefer, {{ dateValue | date:'fullDate' }}</p>

<!-- Output: 9:43 AM -->
<p>The time is {{ dateValue | date:'shortTime' }}</p>
```

Read [more about pipes][angular-pipes] in the developer guide.

## Services

Let's do something more interesting: fetch some jokes from the internet.

To do it "The Angular Way", we'll encapsulate that functionality into a **service**.

Why?
**Components** should not try to do too much;
they should focus on **presenting data** and **delegate data access** to specialized classes.
**Services** are here to fill that role.

This helps your components remain as simple as possible while services handle your business logic.

Let's use Angular CLI to generate a joke service:

```bash
$> ng generate service --spec false services/joke
```

(The `--spec false` option disables the generation of an test file for the service.
We will not cover [automated tests][angular-testing] in this tutorial, but you should definitely check it out.)

### The joke service

The `src/app/services/joke.service.ts` file has been generated:

```ts
import { Injectable } from '@angular/core';

`@Injectable`()
export `class JokeService` {
  constructor() { }
}
```

Once again, a service is simply a JavaScript class, annotated with the [`@Injectable`][angular-docs-injectable] decorator.
More about that later.

For now, simply add a method which returns a joke:

```ts
`import { Joke } from '../models/joke';`

@Injectable()
export class JokeService {
  constructor() { }

* getJoke(): Joke {
*   return { text: 'Knock knock' };
* }
}
```

### Providing the joke service

To use the service, you must **provide** it in your module's `providers` array in `src/app/app.module.ts`:

```ts
// Other imports...
`import { JokeService } from './services/joke.service';`

@NgModule({
  // ...
  providers: [
    `JokeService`
  ],
  // ...
})
export class AppModule { }
```

### Injecting the joke service

Once you've done that, you can **inject** it into your component in `src/app/app.component.ts`.

You just have to add a **constructor parameter property**.
While you're at it, also add a **method to add a joke**:

```ts
// Other imports...
*import { JokeService } from './services/joke.service';

export class AppComponent {
  // ...
  constructor(`private jokeService: JokeService`) {
    // ...
  }

* addJoke() {
*   this.jokes.push(this.jokeService.getJoke());
* }
  // ...
}
```

#### Calling a method from a button

To use our new method,
you can add a button in the template in `src/app/app.component.html`:

```html
<p>
  <button type='button' (click)='addJoke()'>Add joke</button>
</p>
```

The `(click)` attribute is Angular's syntax to listen to the `click` event on a DOM element and trigger something when it occurs.

### Why does it work?

Our component now uses the service.
But why does it work?
All you did was add a parameter property to the constructor:

```ts
constructor(`private jokeService: JokeService`) {
  // ...
}
```

As a reminder, in TypeScript this is equivalent to:

```ts
export class AppComponent {
  `jokeService: JokeService;`

  constructor(`jokeService: JokeService`) {
    `this.jokeService = jokeService;`
  }
}
```

You **never instantiated the service with `new`**, so where is the instance coming from?

### Dependency injection

Angular relies on [dependency injection][di] to plug components, services and other elements together.

* After creating your service, you **provided** it in the application **module**.
* This makes it possible for Angular's **injector** to know that your service exists and to create instances of it.
* By adding the parameter to the component's constructor, you **asked Angular to inject** an instance of the service at runtime.

Dependency injection is a form of [inversion of control][ioc],
meaning that parts of your code **receive** the flow of control instead of driving it like in classic procedural programming.
The general goal is to:

* **Decouple** the execution of a task from implementation.
* **Focus** a component on the task it is designed for.
* **Free components from assumptions** about how other systems do what they do and instead rely on **contracts**.
* **Prevent side effects** when **replacing** a component.

#### Why dependency injection?

**Strong coupling**

```js
function Car() {
  this.engine = new Engine(24);
}
function Engine(gasLead) {
  this.gas = new Gas(gasLead);
}
function Gas(lead) {
  this.lead = lead;
}
```

**Loose coupling** (with an *injector*)

```js
function Car(engine) {
  this.engine = engine;
}
function Engine(gas) {
  this.gas = gas;
}
function Gas(lead) {
  this.lead = lead;
}
```

## Observable data

Our current `getJoke()` method has a **synchronous** signature; implying that data is returned right away:

```ts
const joke = jokeService.getJoke();
```

This will **not** work when fetching jokes from a **remote server**, which is inherently an **asynchronous** operation.

The `getJoke()` method must be modified to not immediately return a joke, but to have an asynchronous signature instead.
It could take a **callback** or return a [**Promise**][js-promise].

Another solution is to return an **Observable**.
Angular includes the [RxJS][rxjs] library for reactive programming using Observables,
to make it easier to compose asynchronous or callback-based code.

### What (the hell) is an observable?

An observable is an **asynchronous data stream**, meaning that it allows you to observe **multiple events over time**.

For example, a user's **mouse clicks** on a website could be easily be modeled as an observable:
there will be several of them and they will happen at different times in the future.

### What (the hell) is reactive programming?

Basically, **reactive programming** is programming with **asynchronous** data **streams**.

RxJS is a library which provides an amazing toolbox of functions to **combine, create and filter** any of those streams.

In Angular 2+, many asynchronous operations are represented as Observable streams.
For example, making an **HTTP call** will return an **Observable** which emits either a **response** or an **error**.
You may **subscribe** to that observable to be notified of the result of the asynchronous call.

To learn more about reactive programming,
you may want to read ["The introduction to Reactive Programming you've been missing"][intro-to-reactive-programming].

### Making `getJoke()` observable

Since Angular's `HttpClient` returns **Observables**, that's what we'll use.

For now, let's modify the signature of our `getJoke()` method in `JokeService` in `src/app/services/joke.service.ts` to return an Observable,
without actually making an HTTP call yet:

```ts
// Other imports...
*import { Observable } from 'rxjs/Observable';
*import 'rxjs/add/observable/of';

@Injectable()
export class JokeService {
  // ...
  getJoke(): `Observable<Joke>` {
    return `Observable.of({ text: 'Knock knock' })`;
  }
}
```

`Observable.of` allows us to create a stream which will simply emit the specified value (or values) and complete.

In this case, we created an Observable which will emit one joke.

### Subscribing to an Observable

Of course, the code in our component no longer works now,
since it expects a `Joke` and gets an Observable of a `Joke` instead:

```
ERROR in src/app/app.component.ts(26,21): error TS2345:
  Argument of type 'Observable<Joke>' is not assignable to parameter of type 'Joke'.
  Property 'text' is missing in type 'Observable<Joke>'.
```

Use the `subscribe` method of the Observable to be notified when a Joke is emitted on the stream in `AppComponent` in `src/app/app.component.ts`:

```ts
addJoke() {
* this.jokeService.getJoke().subscribe(joke => {
*   this.jokes.push(joke);
* });
}
```

We now have our **asynchronous** implementation:

* We **subscribe** to the Observable when `addJoke` is called.
* But the **callback** adding the new joke into the array will be called **later**,
  after the data has been fetched from the remote server.

## Making HTTP calls

Time to actually fetch some jokes from the internet.
We'll need Angular's [`HttpClient`][angular-docs-http-client].
It is part of `HttpClientModule`,
so we need to provide that to our own application module, `AppModule`, in `src/app/app.module.ts`:

```ts
// Other imports...
*import { HttpClientModule } from '@angular/common/http';

@NgModule({
  // ...
  imports: [
    BrowserModule,
    FormsModule,
    `HttpClientModule`
  ],
  // ...
})
export class AppModule { }
```

### Injecting `HttpClient`

Earlier we annotated `JokeService` with the [`@Injectable`][angular-docs-injectable] decorator.
This not only makes it available to the **injector** for creation,
but also allows it to **inject dependencies of its own**.

Now that `HttpClientModule` is available, you can inject `HttpClient` into `JokeService` in `src/app/services/joke.service.ts`:

```ts
// Other imports...
*import { HttpClient } from '@angular/common/http';

@Injectable()
export class JokeService {
  constructor(`private httpClient: HttpClient`) { }
  // ...
}
```

### Joke API response

The API we are going to call returns JSON data that looks like this:

```json
{
  "type": "success",
  "value": {
    "categories": [],
    "id": 1,
    "joke": "Knock knock"
  }
}
```

This does not fit our `Joke` model, which only has a `text` property.

#### Joke API response model

Let's create a new `JokeResponse` model that we can use with this API:

```bash
$> ng generate class models/joke-response
```

This generates a new model file in `src/app/models/joke-response.ts`.
Update it to reflect the **structure** of the API response.
Since it's a nested structure, we'll need **2 classes**:

```ts
export class JokeResponse {
  type: string;
  value: JokeResponseValue;
}

export class JokeResponseValue {
  categories: string[];
  id: number;
  joke: string;
}
```

### Making a GET call

We can now update `getJoke()` in `src/app/services/joke.service.ts` to make an actual HTTP call:

```ts
// Other imports...
*import { JokeResponse } from '../models/joke-response';

@Injectable()
export class JokeService {
  // ...
  getJoke(): Observable<Joke> {
*   return this.httpClient
*     .get<JokeResponse>('https://api.icndb.com/jokes/random');
  }
}
```

As you can see, [`HttpClient`][angular-docs-http-client]'s `get` method is **generic**,
and Angular will take care of parsing the response body and giving us an object of the right type.
But we're still left with one problem: we need an Observable of `Joke` objects, and have one of `JokeResponse` objects instead:

```
ERROR in src/app/services/joke.service.ts(15,5): error TS2322:
  Type 'Observable<JokeResponse>' is not assignable to type 'Observable<Joke>'.
  Type 'JokeResponse' is not assignable to type 'Joke'.
  Property 'text' is missing in type 'JokeResponse'.
```

### Transforming data

We need to be able to transform a `JokeResponse` object into a `Joke`.
Let's add a utility function at the bottom of the file in `src/app/services/joke.service.ts`:

```ts
function convertJokeResponseToJoke(response: JokeResponse): Joke {
  return {
    text: response.value.joke
  };
}
```

### Transforming Observable streams

Similarly to the [`map`][js-array-map] method of JavaScript arrays, Observables have a [`map`][observable-map] operator,
which allows you to transform each item emitted in the stream:

To use it, you need to import it and use the Observable's `pipe` method in `JokeService` in `src/app/services/joke.service.ts`:

```ts
// Other imports...
*import { map } from 'rxjs/operators';

// ...
  getJoke(): Observable<Joke> {
    return this.httpClient
      .get<JokeResponse>('https://api.icndb.com/jokes/random')
*     .pipe(map(convertJokeResponseToJoke));
  }
```

### Reacting to errors in observable streams

An observable stream may emit an **error**.
You can be notified of that error by passing a second callback function to `subscribe` in `AppComponent` in `src/app/app.component.ts`:

```ts
addJoke() {
  this.jokeService.getJoke().subscribe(joke => {
    this.jokes.push(joke);
  }`, err => {`
    `console.warn('Could not get new joke', err);`
  `}`);
}
```

For the purpose of testing this new behavior,
you can produce an error by changing the URL in `JokeService`in `src/app/services/joke.service.ts`,
so that the call fails.
You should then see an error in the console when adding a joke:

```ts
getJoke(): Observable<Joke> {
  return this.httpClient
    .get<JokeResponse>('https://`foo.example.com`/jokes/random')
    .pipe(map(convertJokeResponseToJoke));
}
```

You can then change it back to the correct URL.

### Getting the HTTP response

We've seen that by default, Angular's `HttpClient` returns only the **body of the response**
(this is a *generic example*; do **not** make this change to the project):

```ts
function getJoke(): Observable<JokeResponse> {
  return this.httpClient
    .get<JokeResponse>('https://api.icndb.com/jokes/random');
}

getJoke().subscribe(jokeResponse => {
  // "jokeResponse" has type JokeResponse
  console.log(jokeResponse.value.joke);
  // "Chuck Norris can make a class that is both abstract and final."
});
```

That's nice, but in some cases we might need access to the **HTTP status** or **headers** sent by the server in the response.

#### Observing the response

To get Angular's `HttpClient` to give you the full [`HttpResponse`][angular-docs-http-response] object,
you need to pass an additional options object to your HTTP call,
with the `observe` property set to `"response"` (this is also a *generic example*):

```ts
function getJoke(): Observable<`HttpResponse<JokeResponse>`> {
  `const options = { observe: 'response' };`
  return this.httpClient
    .get<JokeResponse>('https://api.icndb.com/jokes/random'`, options`);
}

getJoke().subscribe(httpResponse => {
  // "httpResponse" has type HttpResponse<JokeResponse>
  console.log(httpResponse.status); // 200
  // "httpResponse.body" has type JokeResponse
  console.log(httpResponse.body.value.joke);
  // "Chuck Norris can make a class that is both abstract and final."
});
```

Now, you no longer get an Observable of `JokeResponse` objects,
but instead get an Observable of `HttpResponse<JokeResponse>` objects.
That is, the full HTTP response, with its `body` already parsed as a `JokeResponse` object.

Read [the documentation of the `HttpResponse` class][angular-docs-http-response] to see what information you can extract from the response.

## Component interaction

As described earlier, components are Angular's fundamental building blocks.

We're going to add a few features to our application:

* The ability to **vote** on which are the best jokes.
* The ability to see the **total** number of votes and how many votes the **best** joke has had.
* The ability to **clear** all the collected votes.

We could implement all of this in `AppComponent`,
but that would not be viable in a real-world scenario with more complex features.
When you have a complex page with multiple areas that each have their specific logic,
it's good practice to **isolate each part into a component**:

### Adding votes to the model

Update the `Joke` model in `src/app/models/joke.ts` to have a `votes` property:

```ts
export class Joke {
  text: string;
* votes: number;
}
```

You need to update `src/app/app.component.ts` to set the initial votes to `0`:

```ts
this.jokes = [
  { text: 'Knock knock'`, votes: 0` },
  { text: 'The cake is a lie'`, votes: 0` }
];
```

You also need to update the `convertJokeResponseToJoke` function in `src/app/services/joke.service.ts`:

```ts
function convertJokeResponseToJoke(response: JokeResponse): Joke {
  return {
    text: response.value.joke,
*   votes: 0
  };
}
```

### Creating a child component

Let's generate our **new component**, the `JokeComponent`:

```ts
$> ng generate component --spec false components/joke
```

This will create a component in the `src/app/components/joke` directory,
with its own TypeScript definition, HTML template and CSS styles.

#### The `JokeComponent`

The responsibility of the new `JokeComponent` will be to display a `Joke` object,
and to provide a button to vote on the joke.

Let's add a `joke` property to the new component in `src/app/components/joke/joke.component.ts`:

```ts
// Other imports...
*import { Joke } from '../../models/joke';

@Component({
  selector: 'app-joke',
  templateUrl: './joke.component.html',
  styleUrls: ['./joke.component.css']
})
export class JokeComponent implements OnInit {
* joke: Joke;
  // ...
}
```

And update the component's template in `src/app/components/joke/joke.component.html` to display the joke's text:

```html
{{ joke.text }}
```

### Passing data from parent to child with input binding

We want the joke to be provided by the parent component, `AppComponent`.
It's an **input** of the `JokeComponent`.
Annotating a component's property with the [`@Input`][angular-docs-input] decorator marks it as an **input property** which can be set by a parent component.
You can do this in `src/app/components/joke/joke.component.ts`:

```ts
// Other imports...
import { Component, `Input`, OnInit } from '@angular/core';

// ...
export class JokeComponent implements OnInit {
  `@Input()`
  joke: Joke;
  // ...
}
```

You can now use the `JokeComponent` in the main component's template in `src/app/app.component.html`.
You need to create an `<app-joke>` tag (matching the component's selector),
and to set the `joke` input property:

```html
<ul>
  <li *ngFor='let joke of jokes'>`<app-joke [joke]='joke'></app-joke>`</li>
</ul>
```

### Voting on jokes

Now that `JokeComponent` is working, we can use it to **handle the logic related to one joke**, like voting.

Add a `vote()` method to `JokeComponent` in `src/app/components/joke/joke.component.ts`:

```ts
vote() {
  this.joke.votes++;
}
```

Add these 2 lines to the component's template in `src/app/components/joke/joke.component.html`:

```html
{{ joke.text }}
*({{ joke.votes }} votes)
*<button type='button' (click)='vote()'>+1</button>
```

You can now vote!

### Displaying global voting information

Let's now display the **total number of votes** and the **best vote** on the page.
That's the job of the **main component**, since a `JokeComponent` only knows about its own joke,
so it can't know the total number of votes or whether its number of votes is the highest.

Add this information to `AppComponent` in `src/app/app.component.ts`:

```ts
export class AppComponent {
  // ...
* bestVote: number;
* totalVotes: number;

  constructor(private jokeService: JokeService) {
*   this.bestVote = 0;
*   this.totalVotes = 0;
    // ...
  }
  // ...
}
```

And display it in the template in `src/app/app.component.html`:

```html
<p>Total votes: {{ totalVotes }}, best vote: {{ bestVote }}</p>
```

### Output from child components

The vote button is in the child component's template, so `AppComponent` can't put an event listener on it directly.
Instead, we need our `JokeComponent` to have an **output** that its parent can listen to.

Annotating a component's property with the [`@Output`][angular-docs-output] decorator marks it as an **output property**.
It must be an [`EventEmitter`][angular-docs-event-emitter] (or an Observable).
Let's add one to `JokeComponent` in `src/app/components/joke/joke.component.ts` now:

```ts
import { Component, `EventEmitter`, Input, OnInit, `Output` } from '@angular/core';

// ...
export class JokeComponent implements OnInit {
  // ...
* @Output()
* voted: EventEmitter<Joke>;

  constructor() {
*  this.voted = new EventEmitter();
  }

  vote() {
    this.joke.votes++;
*   this.voted.emit(this.joke);
  }
}
```

### Listening to child component events from a parent

Let's add an `onJokeVoted()` method to `AppComponent` in `src/app/app.component.ts`:

```ts
onJokeVoted(joke: Joke) {
  this.totalVotes++;
  if (joke.votes > this.bestVote) {
    this.bestVote = joke.votes;
  }
}
```

We want this method to be called every time a vote button is clicked in a child `JokeComponent`.

From the parent's point of view, an **output property** of a child component is **just like any other DOM event**.
You bind to it using Angular's `(event)='expression'` syntax, exactly like you bind to `(click)` on a `<button>` tag.
Do that in `src/app/app.component.html`:

```html
<app-joke [joke]='joke' `(voted)='onJokeVoted(joke)'`></app-joke>
```

### Clearing the votes

Now that our components are already plugged together,
adding the functionality to **clear the votes** is trivial.
Add a `clearVotes()` method to the main component in `src/app/app.component.ts`.
It simply resets all votes to zero, including the jokes':

```ts
clearVotes() {
  this.bestVote = 0;
  this.totalVotes = 0;
  this.jokes.forEach(joke => joke.votes = 0);
}
```

And add a button to call it in the template in `src/app/app.component.html`:

```html
<button type='button' (click)='clearVotes()'>Clear votes</button>
```

It just works!

The `Joke` objects in the `JokeComponent` children are the same objects as the ones in the main component's `jokes` array, bound through Angular's input properties.
When you modify them in any component, Angular **automatically updates all the relevant templates**.

### More component interaction

These were just a few examples of how to communicate between components.

There are other ways to do it, like injecting the same **service** into multiple components.
This can be useful if two components must communicate but neither is a parent of the other, so they cannot use inputs or outputs.

Read the [documentation][angular-component-interaction] to learn more.

## Forms

Angular provides **validation** services for forms and controls.
These validations are performed **client-side** for a better user experience: the user gets **instant feedback**.

However, keep in mind that although this provides a good user experience, it can easily be circumvented and thus **cannot be trusted**.
**Server-side validation is still necessary** for a secure application.

### HTML validations

HTML 5 has [built-in validation attributes][html-input] to define validations on your form inputs (e.g. `<input>`, `<textarea>`, etc):

Attribute   | Description
:---        | :---
`min`       | Minimum value for a number
`max`       | Maximum value for a number
`minlength` | Minimum length for a string
`maxlength` | Maximum length for a string
`pattern`   | Regular expression for a string
`required`  | Required field

You simply add them to the HTML tag:

```html
<input type='text' `required minlength=2` />
```

Usually the **browser** performs these validations.
But Angular **overrides** these and provide its own implementation.
This allows you to add **more complex validations and interaction**.

### Creating a form

Let's turn our lonely greeting input field into a proper form:

* Wrap that part of the template in a `<form>` tag.
* Add a `name` attribute to the input field (required by Angular).
* Add a `required` attribute to the input field to have some validation.
* Add a submit `<button>` tag to complete the form.

```html
*<form>
  <p>
    <input type='text' placeholder='Who are you?' [(ngModel)]='greeting'
      `name='greeting' required` />

    `<button type='submit'>Submit</button>`
  </p>
*</form>
```

#### Updating the component

Let's now make it so that the greeting will only be displayed if submitted through the form.
We need to add a separate property to our component:

* The `greeting` property will represent the value of the input field.
* The `displayedGreeting` property will represent the submitted value (which will no longer be bound to the input field).

We also need a new `displayGreeting()` method which will take the current value of `greeting` and copy it to `displayedGreeting`:

```ts
// ...
export class AppComponent {
  // ...
  greeting: string;
* displayedGreeting: string;
  // ...

* displayGreeting() {
*   this.displayedGreeting = this.greeting;
*   console.log('Greeting displayed');
* }
}
```

#### Listening to form submit events

Update the component's template to reflect the fact that we now want to display `displayedGreeting` instead of `greeting`:

```html
<p *ngIf='displayedGreeting'>
  {{ hello(displayedGreeting) | exclamation:3 }}
</p>
```

Bind the new `displayGreeting()` method to the form's `submit` event to make it work:

```html
<form `(submit)='displayGreeting()'`>
```

### Checking the validation state

You might have noticed that we have marked the input field as **required**,
but that the user can **still submit the form** when it is invalid (i.e. the input field is empty).

That's not very user-friendly.
We're going to make the following improvements:

* **Prevent the form's submission** if it has invalid fields.
* **Disable the submit button** if the form has invalid fields.
* **Display an error message** when the greeting input field contains an invalid value.
* **Set the input field background color to red** if it contains an invalid value.

#### Prevent the form's submission

In Angular, any `<form>` tag is enriched by the [`NgForm`][angular-docs-ng-form] directive.
You can retrieve the instance of the directive attached to the form by using a [**template reference variable**][angular-template-reference-variable]
(`#greetingForm` in this example):

```html
<form `#greetingForm='ngForm'` (submit)='displayGreeting(`greetingForm`)'>
```

We can now update the implementation of `displayGreeting()` to add this new argument.

[`NgForm`][angular-docs-ng-form] must be imported from `@angular/forms`.
This class provides, among other things, a `valid` (or `invalid`) attribute to check whether all the fields are valid or not:

```ts
*import { NgForm } from '@angular/forms';
// ...

displayGreeting(`form: NgForm`) {
  `if (form.valid) {`
    this.displayedGreeting = this.greeting;
    console.log('Greeting displayed');
  `}`
}
```

#### Disable the submit button

The `#greetingForm` template reference variable is already available in the template from the previous modification,
since we passed it to `displayGreeting()` as an argument.

You can also bind it to DOM elements or their attributes elsewhere in the template.

This time, we'll use [`NgForm`][angular-docs-ng-form]'s `invalid` attribute.
We simply have to bind the value of the `<button>` tag's `disabled` attribute to it:

* When the form is **invalid** (`greetingForm.invalid` is true), the button should be **disabled** (`disabled` should be true).
* When the form is **valid** (`greetingForm.invalid` is false), the button should **not be disabled** (`disabled` should be false).

```html
<button type='submit' `[disabled]='greetingForm.invalid'`>Submit</button>
```

#### Display an error message

We've seen that the `<form>` tag is **enriched** with the [`NgForm`][angular-docs-ng-form] **directive**,
and that it's possible to **retrieve that directive** to gain access to the **form's validation state**.

You can do the same with the `<input>` tag, by retrieving the field's [`NgModel`][angular-docs-ng-model]'s directive
(which you applied by using `[(ngModel)]='expression'`):

```html
<input type='text' placeholder='Who are you?' [(ngModel)]='greeting'
  name='greeting' required `#greetingInput='ngModel'` />
```

The `NgModel` directive also has the `valid` and `invalid` attributes,
indicating whether that particular field is valid.
All we have to do is add an error message to the form, and, through judicious use of our old friend the `NgIf` directive,
only display the message when the field is invalid.

```html
<form #greetingForm='ngForm' (submit)='displayGreeting(greetingForm)'>
  <!-- ... -->
* <p *ngIf='greetingInput.invalid'>
*   Name is required
* </p>
</form>
```

##### Dirty, pristine, touched, untouched

That's nice, but the error message is displayed right away.
It makes sense, since the **initial value** of the input field's **is actually invalid**.
But that's not very user-friendly.
Ideally, we would want the error message to be displayed **only once the user has interacted with the form**.

Enter the following `NgForm` and `NgModel` attributes:

* `dirty` - A control is **dirty** if the user has **changed its value**.
* `pristine` - A control is **pristine** if the user has **not yet changed its value** (the opposite of `dirty`).
* `touched` - A control is **touched** if the user has triggered a **[`blur`][blur-event] event** on it.
* `untouched` - A control is **untouched** if the user has **not yet** triggered a **[`blur`][blur-event] event** on it (the opposite of `touched`).

Make the following change to only display the error message after the user has started typing:

```html
<p *ngIf='greetingInput.invalid` && greetingInput.dirty`'>
  Name is required
</p>
```

#### Set the input field background color to red

Angular automatically **mirrors** many `NgModel` **properties** onto the `<input>` tag as **CSS classes**.
You can use these classes to **style** form elements according to the state of the form.

These are some of the supported classes ([full list][angular-form-control-status-classes]):

* `.ng-valid` or `.ng-invalid` is applied depending on whether the value is valid
* `.ng-pristine` or `.ng-dirty` is applied depending on whether the user has changed the value
* `.ng-untouched` or `.ng-touched` is applied depending on whether the user has triggered `blur` event

So when our field is invalid and dirty, it will have both the `.ng-invalid` and `.ng-dirty` CSS classes added to it.
All you need to do is modify `src/app/app.component.css` to add a background color to input fields with this combination of classes:

```css
input.ng-invalid.ng-dirty {
  background-color: #ffc0c0;
}
```

### Angular validators

These are some of the validators provided **out of the box** by Angular:

* [`email`][angular-docs-email-validator] - Validates that a string is a valid e-mail address.
* [`min`][angular-docs-min-validator] & [`max`][angular-docs-max-validator] - Validate that a number is within the specified bound(s).
* [`min-length`][angular-docs-min-length-validator] & [`max-length`][angular-docs-max-length-validator] - Validate that a string's length is within the specified bound(s).
* [`pattern`][angular-docs-pattern-validator] - Validates that a value matches a regular expression.
* [`required`][angular-docs-required-validator] - Validates that a value is present.

Here's a few usage examples:

```html
<input `type='email'` name='email' />
<input type='number' name='age' `min='3' max='10'` />
<input type='text' name='firstName' `min-length='1' max-length='50'` />
<input type='text' name='lastName' `pattern='[a-zA-Z ]*'` />
<input type='text' name='occupation' `required` />
```

### Custom validators

These validators are nice, but you might need **more complex validations**.

That's why Angular allows you to implement [custom validators][angular-custom-validators].
Here's an example of a validator that ensures a string is not in a list of forbidden values:

```ts
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';

export function notInValidator(notIn: string[]): ValidatorFn {
  return (control: AbstractControl): ValidationErrors | null => {

    // Check if the value is invalid.
    if (notIn.indexOf(control.value) >= 0) {
      // Return an error named after the validator if that is the case.
      return {
        notIn: { value: control.value }
      };
    }

    // Otherwise, all is well, there is no error.
    return null;
  };
}
```

#### Registering a custom validator

To use your validation function in a form, you need to wrap it in a directive:

```ts
import { Directive, Input } from '@angular/core';
import { AbstractControl, NG_VALIDATORS, ValidationErrors,
         Validator } from '@angular/forms';

import { notInValidator } from './not-in-validator';

@Directive({
  selector: '[notIn]',
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: NotInValidatorDirective,
      multi: true
    }
  ]
})
export class NotInValidatorDirective implements Validator {

  @Input('notIn')
  notIn: string[];

  validate(control: AbstractControl): ValidationErrors | null {
    return notInValidator(this.notIn)(control);
  }
}
```

#### Using a custom validator

You must register the new directive in the module's `declarations` array:

```ts
// Other imports...
*import { NotInValidatorDirective } from './validators/not-in-validator-directive';

@NgModule({
  declarations: [
    AppComponent,
    ExclamationPipe,
    `NotInValidatorDirective`
  ],
  // ...
})
export class AppModule { }
```

You can then finally use it in the template:

```html
<input type='text' placeholder='Who are you?' [(ngModel)]='greeting'
  name='greeting' required `[notIn]='["Bob"]'` #greetingInput='ngModel' />
```

### Displaying different messages for different errors

There's a little problem now.
Since our error message is displayed as soon as there's an error on the `greetingInput` field,
it always displays `Name is required`, even if the error is due to our new custom validator.

```html
<p *ngIf='`greetingInput.invalid` && greetingInput.dirty'>
  Name is required
</p>
```

To fix that, use `greetingInput.errors` which is an object containing a key for each type of error.
That way you can react separately to the `required` validator's error and to the custom validator's `notIn` error:

```html
<p *ngIf='`greetingInput.errors?.required` && greetingInput.dirty'>
  Name is required
</p>
*<p *ngIf='greetingInput.errors?.notIn && greetingInput.dirty'>
* Name is forbidden
*</p>
```

The special `.errors?.required` syntax with an interrogation mark is here to avoid an error if `.errors` returns `null` or `undefined`,
in which case it will simply ignore the rest of the expression.

### Asynchronous validators

The validator we implemented is actually a function that matches Angular's [`ValidatorFn`][angular-docs-validator-fn] interface.
It is **synchronous**, i.e. it performs no I/O operation to validate its value and immediately returns its errors (or `null`):

```ts
(control: AbstractControl): ValidationErrors | null
```

It's also possible to create **asynchronous validators**.
For example, to check whether a **username is already taken**, you might have to **call your API**, which is an asynchronous operation.

In that case, your validator function must match the [`AsyncValidatorFn`][angular-docs-async-validator-fn] interface instead.
That is, instead of returning an object of validation errors, it must return either a **Promise or an Observable** of that object:

```ts
(control: AbstractControl): Promise<ValidationErrors | null>
                            | Observable<ValidationErrors | null>
```

That way, Angular will wait for the Promise to be resolved or for the Observable to emit the errors before updating the template.

## Reactive forms

The form we have seen so far is a **template-driven form**.
In contrast, **reactive forms** are an Angular technique for creating forms in a **reactive programming** style.
They are provided by a separate module, the [`ReactiveFormsModule`][angular-docs-reactive-forms-module]:

```ts
// Other imports...
import { FormsModule`, ReactiveFormsModule` } from '@angular/forms';

@NgModule({
  // ...
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    `ReactiveFormsModule`
  ],
  // ...
})
export class AppModule { }
```

### Using reactive forms in the component

With reactive forms, the form structure is also defined with code in the component:

```ts
// Other imports...
*import { FormBuilder, FormGroup, NgForm } from '@angular/forms';

// ...
export class AppComponent {
  // ...
  `greetingForm: FormGroup;`

  constructor(
    `private formBuilder: FormBuilder,`
    private jokeService: JokeService
  ) {
    // ...
*   this.greetingForm = formBuilder.group({
*     // Define the "greeting" field and its default value
*     greeting: [ '' ]
*   });
  }

  // ...
}
```

#### Getting the form from the component

Since the form is built directly in the component,
you no longer have to retrieve it from the template.

You can update the `displayGreeting()` method to use the new form group:

```ts
// ...
export class AppComponent {
  // ...

  displayGreeting`()` {
    if (`this.greetingForm`.valid) {
      this.displayedGreeting = this.greeting;
      console.log('Greeting displayed');
    }
  }

  // ...
}
```

#### Reacting to form value changes

Reactive forms do not use `ngModel`, so there won't be two-way binding with the template any longer.
There will only be **one-way binding** from the form group in the component to the template.

To be notified of changes in the form group, you can subscribe to its `valueChanges` property, which is an Observable:

```ts
// ...
export class AppComponent {
  // ...
  constructor(/* ... */) {
    // ...
*   this.greetingForm.valueChanges.subscribe(value => {
*     console.log(`Greeting changed to "${value.greeting}"`);
*     this.greeting = value.greeting;
*   });
  }
  // ...
}
```

### Using reactive forms in the template

With reactive forms, your **template** is somewhat **simplified**.
Remove `ngModel`, the validations, `#greetingForm` and `#greetingInput`.
You simply have to pass the form group created in the component to the `<form>` tag with the `formGroup` directive,
and use the `formControlName` directive on the `<input>` tag:

```html
<form `[formGroup]='greetingForm'` (submit)='`displayGreeting()`'>
  <!-- ... -->
  <input type='text' placeholder='Who are you?' `formControlName='greeting'` />
  <!-- ... -->
</form>
```

You must also update your error messages to get the input field from the form group with `greetingForm.get("greeting")`
instead of using the `#greetingInput` template reference variable you just removed:

```html
<p *ngIf='`greetingForm.get("greeting")`.errors?.required
          && `greetingForm.get("greeting")`.dirty'>
  Name is required
</p>
<p *ngIf='`greetingForm.get("greeting")`.errors?.notIn
          && `greetingForm.get("greeting")`.dirty'>
  Name is forbidden
</p>
```

### Reactive form validations

The validations are no longer applied since we removed them from the template.
With reactive forms, **validation is configured in the component**:

```ts
// Other imports...
import { FormBuilder, FormGroup, NgForm`, Validators` } from '@angular/forms';
*import { notInValidator } from './validators/not-in-validator';

export class AppComponent {
  // ...
  constructor(/* ... */) {
    // ...
    this.greetingForm = formBuilder.group({
      // Define the "greeting" field and its default value
*     greeting: [
*       '',
*       Validators.compose([ // Add validators to the field.
*         Validators.required, // Use the built-in "required" validator.
*         notInValidator([ 'Bob' ]) // Use our custom validator function.
*       ])
*     ]
    });
  }
  // ...
}
```

#### Custom validators in reactive forms

Note that we use our custom validator function (`notInValidator`) directly,
instead of using the `NotInValidatorDirective` wrapper like before:

```ts
Validators.compose([ // Add validators to the field.
  Validators.required, // Use the built-in "required" validator.
  `notInValidator([ 'Bob' ])` // Use our custom validator function.
])
```

This is an advantage of reactive forms over template-driven forms:
validators can be **simple functions** that do not require an additional directive to be applied in the template.

You can remove the directive (e.g. delete `src/app/validators/not-in-validator-directive.ts` and remove it from `declarations` in `src/app/app.module.ts`),
and the form will keep working.

### Which is better, reactive or template-driven?

In [**template-driven forms**][angular-forms], form structure and validation are specified and handled **in the template**:

* Creation of form controls is delegated to directives and asynchronous.
* Angular handles data updates with two-way binding.
* Hard to test with automated tests.

In [**reactive forms**][angular-reactive-forms], a tree of form control objects and validations is managed **in the component** and bound to elements in the template:

* The component class has immediate access to both the data model and the form control structure.
* Changes can be subscribed to in the form of Observables.
* Data and validity updates are synchronous and under your control.
* Easier to test with automated tests.

Neither is "better".
They're two different architectural paradigms, with their own strengths and weaknesses.
You may even use both in the same application.
Read the documentation to learn more.

## Resources

**Documentation**

* [Angular Tour of Heroes Tutorial][angular-tour-of-heroes]
* [Angular Developer Guide][angular-guide]
  * [Template-driven Forms][angular-forms]
  * [Reactive Forms][angular-reactive-forms]
  * [Automated Testing][angular-testing]
* [Angular API reference][angular-api]

**Further reading**

* [A guide to web components][a-guide-to-web-components]
* [Angular 2 components][angular-2-series-components]
* [Understanding, creating and subscribing to observables in Angular][understanding-angular-observables]
* [The Introduction to Reactive Programming You've Been Missing][intro-to-reactive-programming]

[a-guide-to-web-components]: https://css-tricks.com/modular-future-web-components/
[ajax]: https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
[angular]: https://angular.io
[angular-api]: https://angular.io/api
[angular-component-interaction]: https://angular.io/guide/component-interaction
[angular-component-styles]: https://angular.io/guide/component-styles
[angular-custom-validators]: https://angular.io/guide/form-validation#custom-validators
[angular-docs-async-validator-fn]: https://angular.io/api/forms/AsyncValidatorFn
[angular-docs-component]: https://angular.io/api/core/Component
[angular-docs-currency-pipe]: https://angular.io/api/common/CurrencyPipe
[angular-docs-date-pipe]: https://angular.io/api/common/DatePipe
[angular-docs-decimal-pipe]: https://angular.io/api/common/DecimalPipe
[angular-docs-directive]: https://angular.io/api/core/Directive
[angular-docs-email-validator]: https://angular.io/api/forms/EmailValidator
[angular-docs-event-emitter]: https://angular.io/api/core/EventEmitter
[angular-docs-http-client]: https://angular.io/guide/http
[angular-docs-http-response]: https://angular.io/api/common/http/HttpResponse
[angular-docs-injectable]: https://angular.io/api/core/Injectable
[angular-docs-input]: https://angular.io/api/core/Input
[angular-docs-lowercase-pipe]: https://angular.io/api/common/LowerCasePipe
[angular-docs-max-length-validator]: https://angular.io/api/forms/MaxLengthValidator
[angular-docs-min-length-validator]: https://angular.io/api/forms/MinLengthValidator
[angular-docs-max-validator]: https://angular.io/api/forms/Validators#max
[angular-docs-min-validator]: https://angular.io/api/forms/Validators#min
[angular-docs-ng-class]: https://angular.io/api/common/NgClass
[angular-docs-ng-for]: https://angular.io/api/common/NgForOf
[angular-docs-ng-if]: https://angular.io/api/common/NgIf
[angular-docs-ng-form]: https://angular.io/api/forms/NgForm
[angular-docs-ng-model]: https://angular.io/api/forms/NgModel
[angular-docs-ng-module]: https://angular.io/api/core/NgModule
[angular-docs-ng-plural]: https://angular.io/api/common/NgPlural
[angular-docs-ng-style]: https://angular.io/api/common/NgStyle
[angular-docs-ng-switch]: https://angular.io/api/common/NgSwitch
[angular-docs-output]: https://angular.io/api/core/Output
[angular-docs-pattern-validator]: https://angular.io/api/forms/PatternValidator
[angular-docs-percent-pipe]: https://angular.io/api/common/PercentPipe
[angular-docs-pipes]: https://angular.io/api?type=pipe
[angular-docs-reactive-forms-module]: https://angular.io/api/forms/ReactiveFormsModule
[angular-docs-required-validator]: https://angular.io/api/forms/RequiredValidator
[angular-docs-titlecase-pipe]: https://angular.io/api/common/TitleCasePipe
[angular-docs-uppercase-pipe]: https://angular.io/api/common/UpperCasePipe
[angular-docs-validator-fn]: https://angular.io/api/forms/ValidatorFn
[angular-form-control-status-classes]: https://angular.io/guide/form-validation#control-status-css-classes
[angular-forms]: https://angular.io/guide/forms
[angular-guide]: https://angular.io/guide/architecture
[angular-pipes]: https://angular.io/guide/pipes
[angular-reactive-forms]: https://angular.io/guide/reactive-forms
[angular-starter]: https://github.com/MediaComem/comem-angular-starter#readme
[angular-structural-directives]: https://angular.io/guide/structural-directives
[angular-template-reference-variable]: https://angular.io/guide/template-syntax#ref-vars
[angular-testing]: https://angular.io/guide/testing
[angular-tour-of-heroes]: https://angular.io/tutorial
[angular-2-series-components]: http://blog.ionic.io/angular-2-series-components/
[blur-event]: https://developer.mozilla.org/en-US/docs/Web/Events/blur
[chrome]: https://www.google.com/chrome/
[chrome-dev]: https://developers.google.com/web/tools/chrome-devtools/console/
[css-attribute-selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors
[di]: https://en.wikipedia.org/wiki/Dependency_injection
[dom-event]: https://developer.mozilla.org/en-US/docs/Web/API/Event
[html-history-api]: https://developer.mozilla.org/en-US/docs/Web/API/History_API
[html-input]: https://www.w3schools.com/tags/tag_input.asp
[intro-to-reactive-programming]: https://gist.github.com/staltz/868e7e9bc2a7b8c1f754
[jquery]: http://jquery.com
[js]: ../js/
[js-array-map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
[js-classes]: ../js-classes/
[js-closures]: ../js-closures/
[js-modules]: ../js-modules/
[js-promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[ioc]: https://en.wikipedia.org/wiki/Inversion_of_control
[observable-map]: http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map
[rxjs]: http://reactivex.io/rxjs/
[ts]: https://www.typescriptlang.org
[ts-subject]: ../ts
[understanding-angular-observables]: https://hackernoon.com/understanding-creating-and-subscribing-to-observables-in-angular-426dbf0b04a3
[web-components]: https://developer.mozilla.org/en-US/docs/Web/Web_Components

repository: Skyggen/comem-webdev

repo_name: Skyggen/comem-webdev


text:
# wsterm
Text based WebSocket testing utility written in Go

## Contributing

If you wish to make changes to this code that you believe will be useful to others, you can
contribute to the project. If you do, there are a number of policies you should follow:

* Check the issues to see if there are already similar bug reports or enhancements.
* Feel free to add bug reports and enhancements at any time.
* Don't work on things that are not part of an approved project.
* Don't create projects - they are only created the by owner.
* Projects are created based on conversations on the wiki.
* Feel free to initiate or join conversations on the wiki.
* Follow our [Go Coding Standards](https://www.kss.cc/standards/go.html).

license: MIT

repository: klassen-software-solutions/wsterm

branch_name: refs/heads/master

extension: md

gha_language: Go

gha_license_id: MIT

license_type: permissive

repo_name: klassen-software-solutions/wsterm


text:
Title: Google Spreadsheet Integration

Developers: Arun Nagarajan from Google and Daniel McLaughlin from the Boston Globe

Description: Easily search and process petition data directly through Google Spreadsheets. This tool could be a framework to exploring other open APIs within an environment familiar to many researchers and journalists.

Code is very early and cleanup/refactoring needed ;)

![Screenshot of "We the Spreadsheet"](https://f.cloud.github.com/assets/979487/595221/47b9c01c-caeb-11e2-9095-b67156071732.png
)

repository: oscarLiuMinhui/GoogleAppsScript

repo_name: oscarLiuMinhui/GoogleAppsScript


text:
---
layout: post
title: "Daily Bite #40"
tags:
    - learn
    - life
    - daily

category: dailybite
page_type: long
published: true
---

- [How flashing lights and pink noise might banish Alzheimer’s, improve memory and more](https://www.nature.com/articles/d41586-018-02391-6) -- what a great news, beside coffee, people who has this, can improve their memory. and because this was can be inherited, i should be careful.
- [Cracking the Code to build an All-Star Product team](https://blog.gojekengineering.com/cracking-the-code-to-build-an-all-star-product-team-8611f659b11c) -- i kinda follow Gojek Engineering recently, and there's quite a lot of things i could follow or take as an insight to test or experiment.
- [When is a senior engineer not a senior engineer?](https://www.mooreds.com/wordpress/archives/2812) -- where we at?
- [Galaxy S9 Exynos 9810 Hands-On - Awkward First Results](https://www.anandtech.com/show/12478/exynos-9810-handson-awkward-first-results) -- basically, S9 beated by iPhone 8.

gha_language: HTML


text:
# ⛓ Simple-Blockchain ⛓
This is a C# port from ([Python code](https://medium.com/crypto-currently/lets-build-the-tiniest-blockchain-e70965a248b)).

It uses **SHA-256** as **Hash**, I slightly modified the code from the tutorial to get a random string with the System.Security.Cryptography library.

## 🖥 What you can learn from the Code 🖥

- Simply how a **Blockchain** works
- What a **Hash** is, in the context of Blockchain Technologies
- How to use the **Blockchain** in applications 🖥

## 🖼 Example 🖼

![Simple Blockchain C# Command Line](Images/Simple-Blockchain_example.png)


text:
---
# Documentation: https://sourcethemes.com/academic/docs/managing-content/

title: Ordinal regression algorithms for the analysis of convective situations over
  Madrid-Barajas airport
subtitle: ''
summary: ''
authors:
- David Guijo-Rubio
- Carlos Casanova-Mateo
- Juilia Sanz-Justo
- Pedro Antonio Gutiérrez
- Sara Cornejo-Bueno
- César Hervás-Martínez
- Sancho Salcedo-Sanz
tags:
- Convective clouds
- Convective analysis
- Airports
- Machine learning techniques
- Ordinal regression
categories: []
date: '2020-05-01'
lastmod: 2021-04-28T11:37:52+02:00
featured: false
draft: false

# Featured image
# To use, add an image named `featured.jpg/png` to your page's folder.
# Focal points: Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight.
image:
  caption: ''
  focal_point: ''
  preview_only: false

# Projects (optional).
#   Associate this post with one or more of your projects.
#   Simply enter your project's folder or file name without extension.
#   E.g. `projects = ["internal-project"]` references `content/project/deep-learning/index.md`.
#   Otherwise, set `projects = []`.
projects: []
publishDate: '2021-04-28T09:37:52.411852Z'
publication_types:
- '2'
abstract: In this paper we tackle a problem of convective situations analysis at Adolfo-Suarez
  Madrid-Barajas International Airport (Spain), based on Ordinal Regression algorithms.
  The diagnosis of convective clouds is key in a large airport like Barajas, since
  these meteorological events are associated with strong winds and local precipitation,
  which may affect air and land operations at the airport. In this work, we deal with
  a 12-h time horizon in the analysis of convective clouds, using as input variables
  data from a radiosonde station and also from numerical weather models. The information
  about the objective variable (convective clouds presence at the airport) has been
  obtained from the Madrid-Barajas METAR and SPECI aeronautical reports. We treat
  the problem as an ordinal regression task, where there exist a natural order among
  the classes. Moreover, the classification problem is highly imbalanced, since there
  are very few convective clouds events compared to clear days. Thus, a process of
  oversampling is applied to the database in order to obtain a better balance of the
  samples for this specific problem. An important number of ordinal regression methods
  are then tested in the experimental part of the work, showing that the best approach
  for this problem is the SVORIM algorithm, based on the Support Vector Machine strategy,
  but adapted for ordinal regression problems. The SVORIM algorithm shows a good accuracy
  in the case of thunderstorms and Cumulonimbus clouds, which represent a real hazard
  for the airport operations.
publication: '*Atmospheric Research*'
url_pdf: doi.org/10.1016/j.atmosres.2019.104798
doi: 10.1016/j.atmosres.2019.104798
---

repository: dguijo/academic-kickstart

repo_name: dguijo/academic-kickstart


text:
# NerdPress

NerdPress is ebook publishing software written for programmers, designers, and others comfortable with the command line.

## Features

* Generate a new ebook project from the command line.
* Export your book to HTML, PDF, EPUB and MOBI formats.
* Manage and store project files in a simple directory structure.
* Use Markdown and HTML to write sections of your ebook.
* Modify the look and feel of exported versions using CSS and Sass.
* Built to make syntax highlighting and inline code and code block styling a top priority.
* Uses a modular design that lets developers make the changes they need.

## Default Dependencies

Certain tasks rely on external dependencies for proper execution:

* DocRaptor - PDF generation
* ???? - EPUB generation
* ???? - MOBI generation

These dependencies are isolated as Ruby classes within the architecture so that developers are able to swap them out for other equivalent services as needed.

## Installation

Add the gem to an existing project simply  by adding a Gemfile (either via `bundle init`) or by creating one by hand:

```bash
$:> cd new_ebook
$:> bundle init
Writing new Gemfile to /home/user/projects/new_ebook/Gemfile
```

Then add the following line to the Gemfile:

```ruby
gem 'nerdpress'
```

Alternately, you can install the gem globally (or within a gemset depending on how you manage Rubies on your workstation) and use the command line generator to create a new empty project directory.

```bash
$:> gem install nerdpress
$:> nerdpress new new_ebook
```

Both cases use Bundler to manage NerdPress and its dependencies, so:

```bash
$:> bundle install
```

TODO: revisit invocations and outputs after command line generator is working.

## Usage

A NerdPress project is just a local directory that follows a prescribed structure.

```
.
├── images/
├── sections/
├── stylesheets/
├── .gitignore
├── config.yml
└── Gemfile
```

The main text of your book can be written as a sorted set of Markdown and HTML files in the `sections/` directory. NerdPress will automatically recognize any files with common extensions for Markdown or HTML:

```bash
$:> cd new_ebook
$:> ls -1 sections/
 01_copyright.md
 02_welcome.html
 03_getting_started.markdown
 04_learning_the_ropes.htm
 05_finding_your_feet.mdn
 06_advanced_topics.xhtml
 07_big_conclusion.mdown
```

Assets in your `images/` directory can be referenced from within text sections. NerdPress can identify GIFs, JPEGs, PNGs and SVGs.

```markdown
![](images/diagram.png)
```

When exporting to one of the supported formats, the tool will look for a single stylesheet named for that format by default:

* HTML - `styles/html.(css|scss|sass)`
* PDF - `styles/pdf.(css|scss|sass)`
* EPUB - `styles/epub.(css|scss|sass)`
* MOBI - `styles/mobi.(css|scss|sass)`

Projects that follow these conventions require no additional configuration. Some of these settings can, however, be overridden in the `config.yml` file.

The gem includes commands for exporting the project in one of a number of formats:

```bash
# Build supported ebook formats
$:> nerdpress build epub mobi

# Build HTML and PDF formats
$:> nerdpress build html pdf

# Build all supported formats
$:> nerdpress build

# Same
$:> nerdpress build all
```

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/chriskottom/nerdpress.

## License

The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

## Thanks

Work on this gem and the Rake-based ebook toolchain that came before it was heavily influenced by some of my favorite book-authoring Rubyists:

* Avdi Grimm and [Quarto](https://github.com/avdi/quarto)
* Pat Shaughnessy and his blog post [My eBook build process and some PDF, EPUB and MOBI tips](http://patshaughnessy.net/2012/11/27/my-ebook-build-process-and-some-pdf-epub-and-mobi-tips)

repository: aritode/nerdpress

repo_name: aritode/nerdpress


text:
# Dust Collection Systems & Design

[Bill Pentz - Cyclone and Dust Collection Research](http://billpentz.com/woodworking/cyclone/)

[Homemade wall-mounted boom arm](http://festoolownersgroup.com/festool-jigs-tool-enhancements/homemade-wall0-mounted-boom-arm/)

[The Dust Hub - How to get the most out of just one CT - Video](http://festoolownersgroup.com/festool-jigs-tool-enhancements/the-dust-hub-how-to-get-the-most-out-of-just-one-ct-video/)

Blast gates can be equipped with low voltage magnetic reed switches (alarm switches) that can be used to turn on the dust collector. They could also be used to turn off power to machines whose blast gates are closed.

## Portable Dust Extractors & Accessories

* [Hose Sleeve](https://www.wirecare.com/interest/car-audio/general-wire-cable-protection/flexo-pet/ptn1.50og-flexo-pet-1-1-2-ogre-25-ft-cuts) - 1.5" works well for 27mm hose with a power cord.
* [Heat Shrink]() - 50mm 2:1 shrink
* [Bags]()
* [Filters]()
* [Overhead Hose Management]()

## Stationary Dust Collection System Components

System components, tool specicfic items are listed with the tools.

[Clear Vue Cyclones](http://www.clearvuecyclones.com/)

[Harvey Gyro Air G700](https://www.harveywoodworking.com/products/g700)

[Magport](https://magport.net) – magnectic quick connects for dust collectors and the like

[PowerTec Dust Management Products](http://powertecproducts.com/dust-management/)
* Hose & clamps
* Fittings
* Blast gates
* Swithches

**[Dustopper Cyclone Tops for 5-Gallon Buckets](http://dustopper.com)**
FOG thread: [FESTOPPER - an inexpensive Dust Extractor mounted cyclone](http://festoolownersgroup.com/festool-jigs-tool-enhancements/festopper-an-inexpensive-dust-extractor-mounted-cyclone/).
Sawmill Creek thread: [Dustopper ?!?](https://sawmillcreek.org/showthread.php?266218-Dustopper-) - includes comments from the designer.

[Loc-Line](https://www.loc-line.com/products/2-5-vacuum-hose/) - hose system for dust collection where it is difficult, or not worth the time, to set up a "permanent" system - e.g., drill presses. Anti-static hose and fittings are available. Lee Valley stocks a [limited selection](http://www.leevalley.com/US/wood/page.aspx?cat=1,42401,62604&p=58751) of the non-anti-static components.

[Veritas Cyclone Lids](http://www.leevalley.com/en/wood/page.aspx?p=30282)

repository: DouglasUrner/ShopNotes

repo_name: DouglasUrner/ShopNotes


text:
Thorn (Thor for .NET)
=====================
A command line utility accelerator.

In 30 secs
----------
For building a "Tasks" style command line utility.

1. In VS2010, Create a new "Console Application" project.
2. Install "thorn" from nuget
3. Make your code look like this:

Program.cs:

	class Program
	{
		static void Main(string[] args)
		{
			Thorn.Runner.Run(args);
		}
	}

Protocol.cs:

	[ThornExport]
	public class Protocol
	{
		[Description("Says 'Hello'")]
		public void Hello(HelloOptions opts)
		{
			Console.WriteLine("Hello, {0}!", opts.Target);
		}
	}

	public class HelloOptions
	{
		[Description("Object of the salutation")]
		public string Target { get; set; }
	}

### Run it at the commandline:

	C:\...\bin\Debug>MyApp protocol:hello -t world

### Get Usage Info:

	C:\...\bin\Debug>MyApp help
	C:\...\bin\Debug>MyApp help protocol:hello

In 2 Minutes
------------
Thorn essentially provides a lightweight routing and dispatch layer to you own code. Such
an environment encourages a style of development which relies on application-aware utilities,
and also serves as a good springboard for experimentation, and ensures that one-offs that
work out are already built in a repeatable, deployable, reusable fashion. In short, your
admins will love you.

To facilitate zero-friction "exports to the commandline", Thorn makes a few assumptions.

First it discovers types and methods to be exported via a reflection scan. The default
convention scans the entry assembly for types marked with the `[ThornExport]` attribute
and exports the public methods of those types. Methods marked with the `[ThornIgnore]`
attribute will be skipped.

When an exported method is invoked, it's parameter type is examined and bound from the
commandline switches by cbrianball's excellent Args library. Thorn also leans on Args to
generate the help text about available switches to a command.

Therefore there are a couple of simple requirements on exported types and methods:

- Exported types must be public and instantiable (non-abstract, non-static)
- In the default configuration, exported types must have a default constructor
- Exported methods must be instance methods
- Exported methods must be parameterless or have exactly 1 parameter
- Parameter may be complex. See Args docs for details

### Overriding the defaults

You have the opportunity to bend and break a number of these rules. To set advanced
configuration options, use an initializer as below:

	var runner = Thorn.Runner.Configure(config => {
		config.DoNotScan();
		config.Export(typeof(MyUndecoratedType));

		config.UseTypeScanningConvention(new MyTypeScanningConvention());
	});

	runner.Run(args);

### Dependency Injection

I often wish to have services injected into my exports. Luckily it's pretty easy. To wit:

	var runner = Thorn.Runner.Configure(config => {
		config.UseCallbackToInstantiateExports(ObjectFactory.GetInstance);
	});

### A word on namespaces
Thorn uses the names of types as namespaces, and the names of methods as actions. By
default, a namespace will be required to call an action or get help for it. You can
configure a "default type" as below, and then call actions on that type without a namespace.

So, modifying the 30 second example to

	Thorn.Runner.Configure(config => config.SetDefaultType<Protocol>()).Run(args);
would allow commandline syntax like

	C:\...\bin\Debug>MyApp hello -t world
and

	C:\...\bin\Debug>MyApp help hello

**It is never wrong to use the namespace for a command**

Changelog
---------
####1.0.1:
- Moved home to littlebits on github. Updated project links.
- Deprecating DoNotScan() in lieu of a more precise DoNotScanEntryAssembly()

MIT License
-----------
Copyright (c) 2011 Jace Bennett and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

 IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

repository: little-sharps/thorn

repo_name: little-sharps/thorn


text:
# Go http mock server
> Mock your APIs in a really fast, robust and comprehensive way

## Install
`go get github.com/jaschweder/go-http-mock-server`

## Getting start

Create a ``mock.json`` file like this:
```json
{
    "server":{
        "address":"<IP_ADDRESS>",
        "port":8080
    },
    "routes":[
        {
            "request":{
                "method":"GET",
                "url":"/hello"
            },
            "response":{
                "status":200,
                "body":"{\"message\": \"World!\"}"
            }
        }
    ]
}
```

Run ``gomock``:
```shell
$ gomock mock.json
```

Try make a request:
```shell
$ curl http://localhost:8080/hello
{message: "World!"}
```

That's it! You rock!!!

## How to contribute:

Issue report and PR's are welcome

## Author:
Created by Jonathan A. Schweder<EMAIL_ADDRESS>
## License
MIT


text:
# Build Analysis

The Build Analysis Check makes GitHub Pull Request results more actionable. It is a service to improve the GitHub Pull Request experience by highlighting build and test information most helpful to .NET developers.

## What does it do?

High-level features include:

- Highlight most important failure information
- Add context by combining information in Azure DevOps and Helix
- Reduce distance to most helpful analysis tools, such as Azure DevOps Test Result History for a particular test or the Helix artifact logs

For more details, see the [specifics](Specifics.md) document.

## How do I get it?

Build Analysis is enabled on a per-repository basis. Contact the [.NET Engineering Services Team](https://github.com/dotnet/arcade/wiki/How-to-get-a-hold-of-.NET-Engineering-Services) to request it be enabled in your repository.

**Note**: This feature requires your repository's pull request builds to occur in the `dnceng-public/public` Azure DevOps organization/project. Unfortunately, we cannot accommodate builds that occur in other Azure DevOps organizations (such as DevDiv).

### How do I know if it's enabled in my repository?

An easy way to see if Build Analysis is enabled in your repository is by viewing a pull request (particularly a recent one) and look for the `Build Analysis` check.

![build analysis check on pr](Resources/build_analysis_check_on_pr.png)

Additionally, if you have sufficient permissions on your repository, you can browse to the Installed GitHub Apps settings and verify that the `.NET Helix` app is installed in your repository. (See the following screenshot)

![installed github apps](Resources/installed_github_apps.png)

## How do I use it?

Once enabled, a new GitHub check suite will be included in all pull requests. Navigate to the `Checks` tab, then look for the `.NET Helix` suite.

![checks tab](Resources/checks_tab.png)

The data that is used in the Build Analysis check is provided by each pipeline (in the dnceng/public Azure DevOps project) that your pull request runs. From that data we are able to present you with errors that occurred during the build process, tests that failed, and even match the error messages with currently open [Known Issues](KnownIssues.md).

As each pipeline completes, the Build Analysis Processor evaluates the results from the build (e.g. build failures, test failures) and updates the GitHub check run to reflect errors it detected in your build.

Check out the [specifics](Specifics.md) page for a deeper dive into the features provided by Build Analysis.

## Other Features

Related to the work done for Build Analysis, we also provide the following features:
- [**Automatic Build Retries**](BuildRetryOnboard.md): Configure your repo's pull request builds to automatically retry when it encounters specific errors.
- [**Automatic Test Retries**](Test%20Retry%20Documentation.md): Configure tests in your repo's pull requests to automatically retry when they encounter specific errors. *This feature requires tests to use Helix as it leverages Helix to retry specific tests.*
- [**Test Reporting**](../../AzureDevOps/TestReportingQueries.md): We've collected your test results data into Kusto for ease of querying and put together a few queries to get started.

## Frequently Asked Questions

### Is this useful even if my project does not use Helix?

Yes! The Build Analysis result leverages Azure DevOps history and information to provide context and workflow improvements. Though it may bring additional information for Helix-based execution, it is not required.

### Why am I not seeing all the errors from my build/tests in Build Analysis?

Technical limitations, such as message size and API throttling, constrain the information shown in the check. The service tries to always include the most pertinent information with links to more complete views.

However, we provide links from Build Analysis to logs and test results in Azure DevOps for deeper investigations.

### What benefit does Build Analysis provide over going directly to Azure DevOps?

- One click to see errors that occurred on pipelines your pull request ran through.
- A single place to look at a combination of build and test errors.
- Notification that an error that occurred on your pull request is related to a [Known Issue](KnownIssues.md).
- One click to create a Known Issue related to an error on your pull request for either the product team or infrastructure team.

Was this helpful? [![Yes](https://helix.dot.net/f/ip/5?p=Documentation%5CProjects%5CBuild%20Analysis%5CIntroduction.md)](https://helix.dot.net/f/p/5?p=Documentation%5CProjects%5CBuild%20Analysis%5CIntroduction.md) [![No](https://helix.dot.net/f/in)](https://helix.dot.net/f/n/5?p=Documentation%5CProjects%5CBuild%20Analysis%5CIntroduction.md)

repository: dotnet/arcade

branch_name: refs/heads/main

gha_language: C#

repo_name: dotnet/arcade


text:
# lxdm-mono-light

> Simple light theme for lxdm.

![screenshot](https://raw.githubusercontent.com/aureooms/lxdm-mono-light/master/lxdm-mono-light-screenshot.png)

There is also a [dark version](https://github.com/aureooms/lxdm-mono-dark).

# Install

:exclamation: Make a backup of /etc/lxdm/lxdm.conf before installing.

```sh
git clone https://github.com/aureooms/lxdm-mono-light
cd lxdm-mono-light

# choose a (light) background image
cp ~/images/wallpaper.jpg ./theme/background.jpg

# do not forget to make a backup of /etc/lxdm/lxdm.conf
sudo make install
```

# License

For lxdm-related files, see [lxdm license](http://sourceforge.net/p/lxdm/code/ci/master/tree/).
Otherwise CC0 1.0 Universal.