# Angular Components

## What is a component?

A component is a TypeScript class that has a template, associated css, and implementation.

* Can be composed of other components
* Can use services, directives, pipes, etc.
* Can handle user and system events
* Should have tests to validate functionality

## Creating a component

`ng generate component login` or `ng g c login`

### Generates the following files:

* login.component.html
* login.component.css
* login.component.spec.ts
* login.component.ts

{% code title="app.component.ts" %}

```typescript
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}
```

{% endcode %}

![](https://3208804520-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LHxcOLKU4vpIQfXJm9H%2F-Ll2Ly2tyGJj-t2_aDqw%2F-Ll2M4XEZrhhYOWczyP4%2Fdecorators.jpg?alt=media\&token=b7d47ac1-4c33-479d-8981-5f045379aa55)

* LoginComponent class decorated with @Component
  * selector `<app-login></app-login>` to use component
  * template is set to login.component.html
  * CSS is set to login.component.css

## Components and modules

To use our new component, we will need to add LoginComponent to app.module.ts. The Angular CLI automatically added our new component to the nearest parent module.

{% code title="app.module.ts" %}

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

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

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

{% endcode %}

## Login Component HTML

Our login component needs two inputs for username and password, plus a button to start the login.

{% code title="login.component.ts" %}

```markup
<h1>Login</h1>
<p>
  <label>User Name: </label>
  <input type="text" [(ngModel)]="username" />
</p>
<p>
  <label>
    Password: </label>
  <input type="password" [(ngModel)]="password" />
</p>
<button (click)="submit()">Submit</button>
<p class="message">{{message}}</p>
```

{% endcode %}

`[(ngModel)] = "username"` binds the value of the input to a local variable in the component.

`(click)="submit()"` maps the click event on the button to the submit function

## Login Component

{% embed url="<https://stackblitz.com/edit/angular-fundamentals-ad2019-4dot5?file=src%2Fapp%2Flogin%2Flogin.component.ts&view=editor>" %}

## Component Decorator

* selector - the html name for the component&#x20;
* template - inline template&#x20;
* templateUrl - url to template
* styles - inline styles
* stylesUrl - url to styles file
* providers - objects to be injected into component

{% hint style="warning" %}
Component Providers - be cautious about declaring providers at the component level. It creates a new instance of the service (which are singleton by design) and makes it more complex to mock the service.
{% endhint %}

## Component Hierarchy

* All applications have a root component that Angular bootstraps the application with
* Each page should be a component
* Pages usually are comprised of child components
* Create child components to reduce complexity or when functionality appears in multiple pages

## Lifecycle Hooks

Angular component instances have a lifecycle as Angular creates, updates, and destroys them. A component can implement them, e.g., `export class LoginComponent implements OnInit`

* ngOnInit
  * Initialize the directive/component after Angular first displays the data-bound properties and sets the directive/component's input properties.

    Called *once*, after the *first* `ngOnChanges()`.
* ngOnChanges
  * Respond when Angular (re)sets data-bound input properties. The method receives a [`SimpleChanges`](https://angular.io/api/core/SimpleChanges)object of current and previous property values.

    Called before `ngOnInit()` and whenever one or more data-bound input properties change.
* ngAfterViewInit
  * Respond after Angular initializes the component's views and child views / the view that a directive is in.

    Called *once* after the first [`ngAfterContentChecked()`](https://angular.io/api/core/AfterContentChecked#ngAfterContentChecked).
* ngOnDestroy
  * Cleanup just before Angular destroys the directive/component. Unsubscribe Observables and detach event handlers to avoid memory leaks.

    Called *just before* Angular destroys the directive/component.

{% hint style="info" %}
The lifecycle hook interfaces are optional - since JavaScript doesn't support interfaces, Angular calls any lifecycle methods that are declared. It's considered good practice to implement the interfaces to declare your intent.
{% endhint %}

## Summary

* What is a component?
* How to create components
* HTML templates, data binding, and event handling
* Component Decorator properties
* Lifecycle Hooks
