# <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; } } } } } } ``` ![](https://s3.amazonaws.com/coursetro/posts/content_images/2-1540044855114.png) ## 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%; } } } ``` ![](https://s3.amazonaws.com/coursetro/posts/content_images/4-1540049951026.png) ## 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; } } ``` ![](https://s3.amazonaws.com/coursetro/posts/content_images/5-1540052447578.png)