Angular 10 – CRUD

Angular 10 ( Frontend )

1 – Create app / Crear app

ng new app-tutofox
Would you like to add Angular routing? (y/N): y

2 – Install bootstrap / Instalar bootstrap

ng add @ng-bootstrap/ng-bootstrap

3 – Create module / Crear module

ng generate module person --routing

4 – Create component / Crear componente

ng generate component person/index
ng generate component person/create
ng generate component person/edit

5 – Create routes / Crear rutas

src/app/person/person-routing.module.ts

/.../

import { IndexComponent } from './index/index.component';
import { CreateComponent } from './create/create.component';
import { EditComponent } from './edit/edit.component';
  
const routes: Routes = [
  { path: 'person', redirectTo: 'person/index', pathMatch: 'full'},
  { path: 'person/index', component: IndexComponent },
  { path: 'person/create', component: CreateComponent },
  { path: 'person/:postId/edit', component: EditComponent } 
];

/.../

6 – Create interface / Crear interface

ng generate interface person/person

src/app/person/person.ts

export interface Person {
    id: number;
    name: string;
    email: string;
    phone: number;
}

7 – Create services / Crear servicios

src/app/person/person.service.ts

ng generate service person/person
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

import {  Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

import { Person } from './person';

@Injectable({
  providedIn: 'root'
})
export class PersonService {

  private apiURL = "http://localhost:8000/api/person/";

  httpOptions = {
     headers: new HttpHeaders({
       'Content-Type': 'application/json'
     })
  }

  constructor(private httpClient: HttpClient) { }

  getAll(): Observable<Person[]> {
   return this.httpClient.get<Person[]>(this.apiURL)
   .pipe(
     catchError(this.errorHandler)
   )
 }

 create(person): Observable<Person> {
   return this.httpClient.post<Person>(this.apiURL, JSON.stringify(person), this.httpOptions)
   .pipe(
     catchError(this.errorHandler)
   )
 }

 find(id): Observable<Person> {
   return this.httpClient.get<Person>(this.apiURL + id)
   .pipe(
     catchError(this.errorHandler)
   )
 }

 update(id, person): Observable<Person> {
   return this.httpClient.put<Person>(this.apiURL + id, JSON.stringify(person), this.httpOptions)
   .pipe(
     catchError(this.errorHandler)
   )
 }

 delete(id){
   return this.httpClient.delete<Person>(this.apiURL + id, this.httpOptions)
   .pipe(
     catchError(this.errorHandler)
   )
 }

 errorHandler(error) {
   let errorMessage = '';
   if(error.error instanceof ErrorEvent) {
     errorMessage = error.error.message;
   } else {
     errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
   }
   return throwError(errorMessage);
 }

}

8 – Components / Componentes

Component Index

src/app/person/index/index.component.ts

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

import { PersonService } from '../person.service';
import { Person } from '../person';

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

  persons: Person[] = [];

  // constructor() { }
  constructor(public personService: PersonService) { }

  ngOnInit(): void {
    this.personService.getAll().subscribe((data: Person[])=>{
      this.persons = data;
      console.log(this.persons);
    })
  }

  deletePerson(id){
    this.personService.delete(id).subscribe(res => {
         this.persons = this.persons.filter(item => item.id !== id);
         console.log('Person deleted successfully!');
    })
  }

}

src/app/person/index/index.component.html

<section>

    <div class="d-flex justify-content-between">
      <h4>List person</h4>
      <a routerLink="/person/create" class="btn btn-success">Create New Person</a>
    </div>

    <br>
    
    <table class="table ">
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th width="220px">Action</th>
      </tr>
      <tr *ngFor="let person of persons">
        <td>{{ person.id }}</td>
        <td>{{ person.name }}</td>
        <td>{{ person.email }}</td>
        <td>{{ person.phone }}</td>
        <td>
          <a href="#" [routerLink]="['/person/', 'edit', person.id  ]" class="btn btn-primary">Edit</a>
          <button type="button" (click)="deletePerson(person.id)" class="btn btn-danger">Delete</button>
        </td>
      </tr>
    </table>
 </section>

Component Create

src/app/person/create/create.component.ts

import { Component, OnInit } from '@angular/core';
import { PersonService } from '../person.service';
import { Router } from '@angular/router';
import { FormGroup, FormControl, Validators } from '@angular/forms';

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

  form: FormGroup;

  constructor(
    public personService: PersonService,
    private router: Router
  ) { }

  ngOnInit(): void {

    this.form = new FormGroup({
      name:  new FormControl('', [ Validators.required, Validators.pattern('^[a-zA-ZÁáÀàÉéÈèÍíÌìÓóÒòÚúÙùÑñüÜ \-\']+') ]),
      email: new FormControl('', [ Validators.required, Validators.email ]),
      phone: new FormControl('', [ Validators.required, Validators.pattern("^[0-9]*$") ])
    });

  }

  get f(){
    return this.form.controls;
  }

  submit(){
    console.log(this.form.value);
    this.personService.create(this.form.value).subscribe(res => {
         console.log('Person created successfully!');
         this.router.navigateByUrl('person/index');
    })
  }

}

src/app/person/create/create.component.html

<div>

  <div class="d-flex justify-content-between">
    <h4>Form customer</h4>
    <a href="#" routerLink="/person/index" class="btn btn-primaryt">Back</a>
  </div>

  <hr/>

    <form [formGroup]="form" (ngSubmit)="submit()">

        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="title">Name:</label>
              <input
                formControlName="name"
                id="name"
                type="text"
                class="form-control">
              <div *ngIf="f.name.touched && f.name.invalid" class="alert alert-danger">
                  <div *ngIf="f.name.errors.required">*Name is required.</div>
                  <div *ngIf="f.name.errors.pattern">*The name must only contain letters.</div>
              </div>
            </div>
        </div>

        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="email">Email:</label>
              <input
                formControlName="email"
                id="email"
                type="text"
                class="form-control">
              <div *ngIf="f.email.touched && f.email.invalid" class="alert alert-danger">
                  <div *ngIf="f.email.errors.required">*Email is required.</div>
                  <div *ngIf="f.email.errors.email">*The email must be a valid email address.</div>
              </div>
            </div>
        </div>

        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="phone">Phone:</label>
              <input
                formControlName="phone"
                id="phone"
                type="text"
                class="form-control">
              <div *ngIf="f.phone.touched && f.phone.invalid" class="alert alert-danger">
                  <div *ngIf="f.phone.errors.required">*Phone is required.</div>
                  <div *ngIf="f.phone.errors.pattern">*The phone must only contain numbers.</div>
              </div>
            </div>
        </div>

        <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Submit</button>
    </form>
</div>

Component Edit

src/app/person/edit/edit.component.ts

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

import { PersonService } from '../person.service';
import { ActivatedRoute, Router } from '@angular/router';
import { FormGroup, FormControl, Validators} from '@angular/forms';
import { Person } from '../person';

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

  id: number;
  person: Person;
  form: FormGroup;

  constructor(
    public personService: PersonService,
    private route: ActivatedRoute,
    private router: Router
  ) { }

  ngOnInit(): void {
    this.id = this.route.snapshot.params['idPerson'];
    this.personService.find(this.id).subscribe((data: Person)=>{
      this.person = data;
    });

    this.form = new FormGroup({
      name:  new FormControl('', [ Validators.required, Validators.pattern('^[a-zA-ZÁáÀàÉéÈèÍíÌìÓóÒòÚúÙùÑñüÜ \-\']+') ]),
      email: new FormControl('', [ Validators.required, Validators.email ]),
      phone: new FormControl('', [ Validators.required, Validators.pattern("^[0-9]*$") ])
    });

  }

  get f(){
    return this.form.controls;
  }

  submit(){
    console.log(this.form.value);
    this.personService.update(this.id, this.form.value).subscribe(res => {
         console.log('Person updated successfully!');
         this.router.navigateByUrl('person/index');
    })
  }

}

src/app/person/edit/edit.component.html

<div class="container">
  
    <div class="d-flex justify-content-between">
      <h4>Edit person</h4>
      <a href="#" routerLink="/person/index" class="btn btn-primaryt">Back</a>
    </div>

    <hr>

    <form [formGroup]="form" (ngSubmit)="submit()">


        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="title">Name:</label>
              <input
                formControlName="name"
                [(ngModel)]="person.name"
                id="name"
                type="text"
                class="form-control">
              <div *ngIf="f.name.touched && f.name.invalid" class="alert alert-danger">
                  <div *ngIf="f.name.errors.required">*Name is required.</div>
                  <div *ngIf="f.name.errors.pattern">*The name must only contain letters.</div>
              </div>
            </div>
        </div>

        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="email">Email:</label>
              <input
                formControlName="email"
                [(ngModel)]="person.email"
                id="email"
                type="text"
                class="form-control">
              <div *ngIf="f.email.touched && f.email.invalid" class="alert alert-danger">
                  <div *ngIf="f.email.errors.required">*Email is required.</div>
                  <div *ngIf="f.email.errors.email">*The email must be a valid email address.</div>
              </div>
            </div>
        </div>

        <div class="form-group row">
            <div class="col-md-6 ">
              <label for="phone">Phone:</label>
              <input
                [(ngModel)]="person.phone"
                formControlName="phone"
                id="phone"
                type="text"
                class="form-control">
              <div *ngIf="f.phone.touched && f.phone.invalid" class="alert alert-danger">
                  <div *ngIf="f.phone.errors.required">*Phone is required.</div>
                  <div *ngIf="f.phone.errors.pattern">*The phone must only contain numbers.</div>
              </div>
            </div>
        </div>

        <button class="btn btn-primary" type="submit" [disabled]="!form.valid">Update</button>
    </form>
</div>

9 – Configure person module / Configurar modulo person

src/app/person/person.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { PersonRoutingModule } from './person-routing.module';

import { IndexComponent } from './index/index.component';
import { CreateComponent } from './create/create.component';
import { EditComponent } from './edit/edit.component';

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    IndexComponent,
    CreateComponent,
    EditComponent
  ],
  imports: [
    CommonModule,
    PersonRoutingModule,
    FormsModule,
    ReactiveFormsModule
  ]
})
export class PersonModule { }

10 – Configure App / Configurar App

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { PersonModule } from './person/person.module';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    PersonModule,
    HttpClientModule,
    NgbModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

src/app/app.component.html

<div class="container" style="padding:20px;">
	<h1 style="text-align:center;">
		<a href="/person/index"> Full Stack - Angular 10 & Laravel 8 </a>
	</h1>
	<hr>
  <main>
  <router-outlet></router-outlet>
  </main>
</div>

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *