# <center>Angular 7</center>
## Components
Prerequisite: NPM
For installation
`npm install -g @angular/cli`
Make new project
`ng new [project name]`
Choose what you reliable on styling
Go to Project folder
`cd [project name]`
Open in Visual Studio Code
`code .`
Run server
`ng serve -o`
`ng generate component nav`
`ng g c about`
`ng g c contact`
`ng g c home`
## Templating
Delete unnecessary code in `app.component.html`.
add
```htmlmixed=
<app-nav></app-nav>
<section>
<router-outlet></router-outlet>
</section>
```
add in `nav.component.html`
```htmlmixed=
<header>
<div class="container">
<a routerLink="/" class="logo">apptitle</a>
<nav>
<ul>
<li><a routerLink="/">Home</a></li>
<li><a routerLink="/about">About</a></li>
<li><a routerLink="/contact">Contact us</a></li>
</ul>
</nav>
</div>
</header>
```
To add click change page.
```htmlmixed=
<!-- From: -->
<a routerLink="/">myapp</a>
<!-- To: -->
<a routerLink="/">{{ appTitle }}</a>
```
add in `nav.component.ts`.
```typescript=
export class NavComponent implements OnInit {
appTitle: string = 'myapp';
// OR (either will work)
appTitle = 'myapp';
constructor() { }
ngOnInit() {
}
}
```
Add `styles.css`.
```scss=
@import url('https://fonts.googleapis.com/css?family=Montserrat:400,700');
body, html {
height: 100%;
margin: 0 auto;
}
body {
font-family: 'Montserrat';
font-size: 18px;
}
a {
text-decoration: none;
}
.container {
width: 80%;
margin: 0 auto;
padding: 1.3em;
display: grid;
grid-template-columns: 30% auto;
a {
color: white;
}
}
section {
width: 80%;
margin: 0 auto;
padding: 2em;
}
```
Add `nav/cpmponent.css`.
```scss=
header {
background: #7700FF;
.logo {
font-weight: bold;
}
nav {
justify-self: right;
ul {
list-style-type: none;
margin: 0; padding: 0;
li {
float: left;
a {
padding: 1.5em;
text-transform: uppercase;
font-size: .8em;
&:hover {
background: #8E2BFF;
}
}
}
}
}
}
```

## Routing
Open up ``/src/app/app-routing.module.ts` and specify the following contents:
```typescript=
/ Other imports removed for brevity
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
import { ContactComponent } from './contact/contact.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
];
```
Now you can change the page.
## Event Binding
Visit the`/src/app/home/home.component.html` template file and specify the following:
```htmlembedded=
<h1>Home</h1>
<button (click)="firstClick()">Click me</button>
```
Define the method in the `home.component.ts` file as such:
```typescript=
export class HomeComponent implements OnInit {
constructor() { }
ngOnInit() {
}
firstClick() {
console.log('clicked');
}
}
```
## Class & Style Binding
To add it code.
```htmlembedded=
<h1 [ngStyle]="{
'color': h1Style ? 'gray' : 'black',
'font-size': !h1Style ? '1em' : '4em'
}">Home</h1>
```
## Services
Command line.
`ng generate service data`
Open up the new service file `/src/app/data.service.ts` and let's create the following method:
```typescript=
// Other code removed for brevity
export class DataService {
constructor() { }
firstClick() {
return console.log('clicked');
}
}
```
To use this in a component, visit `/src/app/home/home.component.ts` and update the code to the following:
```typescript=
import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
constructor(private data: DataService) { }
ngOnInit() {
}
firstClick() {
this.data.firstClick();
}
}
```
## HTTP Client
Add in `/src/app/app.module.ts`.
```typescript=
// Other imports
import { HttpClientModule } from '@angular/common/http';
```
In import.
```typescript=
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule, // <-- Right here
],
```
Now use it in our /src/app/data.service.ts` file:
```typescript=
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; // Import it up here
@Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private http: HttpClient) { }
getUsers() {
return this.http.get('https://reqres.in/api/users')
}
}
```
Open up our `home.component.ts` file and modify the following:
```typescript=
export class HomeComponent implements OnInit {
users: Object;
constructor(private data: DataService) { }
ngOnInit() {
this.data.getUsers().subscribe(data => {
this.users = data
console.log(this.users);
}
);
}
}
```
Open up `home.component.html` and specify the following:
```htmlmixed=
<h1>Users</h1>
<ul *ngIf="users">
<li *ngFor="let user of users.data">
<img [src]="user.avatar">
<p>{{ user.first_name }} {{ user.last_name }}</p>
</li>
</ul>
```
In `home.component.scss`:
```css=
ul {
list-style-type: none;
margin: 0;padding: 0;
li {
background: rgb(238, 238, 238);
padding: 2em;
border-radius: 4px;
margin-bottom: 7px;
display: grid;
grid-template-columns: 60px auto;
p {
font-weight: bold;
margin-left: 20px;
}
img {
border-radius: 50%;
width: 100%;
}
}
}
```

## Forms
Visit the `app.module.ts` file and import the Reactive Forms Module:
```typescript=
// other imports
import { ReactiveFormsModule } from '@angular/forms';
// other code
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
ReactiveFormsModule // <- Add here
],
```
visit the `contact.component.ts` file and specify the following.
```typescript=
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-contact',
templateUrl: './contact.component.html',
styleUrls: ['./contact.component.scss']
})
export class ContactComponent implements OnInit {
messageForm: FormGroup;
submitted = false;
success = false;
constructor(private formBuilder: FormBuilder) { }
ngOnInit() {
this.messageForm = this.formBuilder.group({
name: ['', Validators.required],
message: ['', Validators.required]
});
}
onSubmit() {
this.submitted = true;
if (this.messageForm.invalid) {
return;
}
this.success = true;
}
}
```
Visit `contact.component.html`:
```htmlmixed=
<h1>Contact us</h1>
<form [formGroup]="messageForm" (ngSubmit)="onSubmit()">
<h5 *ngIf="success">Your form is valid!</h5>
<label>
Name:
<input type="text" formControlName="name">
<div *ngIf="submitted && messageForm.controls.name.errors" class="error">
<div *ngIf="messageForm.controls.name.errors.required">Your name is required</div>
</div>
</label>
<label>
Message:
<textarea formControlName="message"></textarea>
<div *ngIf="submitted && messageForm.controls.message.errors" class="error">
<div *ngIf="messageForm.controls.message.errors.required">A message is required</div>
</div>
</label>
<input type="submit" value="Send message" class="cta">
</form>
<div *ngIf="submitted" class="results">
<strong>Name:</strong>
<span>{{ messageForm.controls.name.value }}</span>
<strong>Message:</strong>
<span>{{ messageForm.controls.message.value }}</span>
</div>
```
Update the css.
```css=
label {
display: block;
input, textarea {
display: block;
width: 50%;
margin-bottom: 20px;
padding: 1em;
}
.error {
margin-top: -20px;
background: yellow;
padding: .5em;
display: inline-block;
font-size: .9em;
margin-bottom: 20px;
}
}
.cta {
background: #7700FF;
border: none;
color: white;
text-transform: uppercase;
border-radius: 4px;
padding: 1em;
cursor: pointer;
font-family: 'Montserrat';
}
.results {
margin-top: 50px;
strong {
display: block;
}
span {
margin-bottom: 20px;
display: block;
}
}
```
