Angular 9 - CRUD com ASP .NET Core WEB API 3.1 - II


Vamos implementar uma aplicação ASP .NET Core Web API usando a versão 3.1 e realizar as operações CRUD usando o Angular 9.

Continuando a primeira parte do artigo vamos agora criar a aplicação Angular.

recursos usados:

Criando a aplicação Angular

Agora vamos criar um aplicativo front-end do lado do cliente no Angular 9.

Para isso, vamos executar os seguintes comandos do Angular-CLI:

//criar o projeto
ng new <nome_app>

//entrar na pasta do projeto
cd <nome_app>

//abrir app no VS Code
code .

//abrir a app no navegador
ng serve --o

Antes de iniciar vamos definir a estrutura usada em nosso projeto com os respectivos componentes que iremos criar no Angular 9 e seus arquivos.

Vamos aproveitar a estrutura inicial criada do projeto e usar os componentes da pasta app e mais o componente app.service que iremos criar. Assim a estrutura dos componentes pode ser vista abaixo:

● src
+---● app
|    |      |--app.component.ts
|    |      |--app.component.css
|    |      |--app.component.html
|    |      |--app.service.ts
|    |      |--app.model.ts
|    |      |--app.module.ts
|--index.html (caminho cdn para o  bootstrap e fa icons)

Para criar o componente service vamos executar o comando :

ng g s app --skipTests

Nota: As opções –inline Style (Alias: -s) e –skip Tests são usadas para ignorar os arquivos de estilo e de teste (extensão - .spec.ts), respectivamente.

Então vamos lá...

Vamos criar um projeto Angular chamado PagamentoCartao, entrar na pasta do projeto e abrir o projeto no VS Code:

ng new PagamentoCartao
cd PagamentoCartao
code .

Nota:  Ao emitir o comando ng new <nome> será perguntado sobre o uso de rotas (Would you like to add Angular Routing?) ao responder “Yes”, já temos tudo que precisamos para o roteamento.

Abaixo temos a estrutura do projeto criado:

  1. e2e” - pasta contendo os arquivos de testes e configurações para realizar testes;
  2. node_modules” - pasta contendo todos os pacotes restaurados a partir das dependências definidas no arquivo package.json;
  3. src/” - pasta da aplicação principal que contém a pasta app, os templates HTML, os componentes, módulos, etc.;
  4. "tsconfig.json, index.html, etc” - arquivos essenciais necessários para rodar a aplicação;
  5. packages.json” - contém a referência a todos os pacotes necessários para a nossa aplicação Angular 2;

Nota: Eu apaguei a pasta test.ts do projeto

Dentro da pasta src estão contidos os componentes, os módulos e serviços:

Na pasta app temos os seguintes arquivos:
  • app-routing.module.ts - arquivo de rotas;
  • app.component.css - arquivo de estilo;
  • app.component.html - arquivo html contendo código HTML que será exibido na view;
  • app.component.spec.ts - arquivo de testes;
  • app.component.ts - arquivo principal que possui a lógica da aplicação;
  • app.module.ts - arquivo de módulo que agrupa os componentes, diretivas, pipes e serviços usados na aplicação

A sintaxe dos nomes dos arquivos segue o guia de estilo do Angular : https://angular.io/guide/styleguide

Obs:  Neste exemplo eu não vou criar testes e por isso não vou criar arquivos de testes e vou remover os arquivos terminados em *spec.ts

 

Vamos agora criar o componente de serviço no projeto:

Agora a estrutura do nosso projeto Angular a partir da pasta src ficou assim:

Como vamos usar o Bootstrap temos que adicionar uma referência no arquivo index.html:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>PagamentoCartao</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">

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

Vamos  a segior incluir  o código abaixo no arquivo app.service.ts que define os métodos para acessar a nossa API:

import { Injectable } from '@angular/core';
import { HttpClient,HttpHeaders }    from '@angular/common/http';  
@Injectable({
  providedIn: 'root'
})
export class AppService {  
  readonly rootURL = 'http://localhost:1168/api';
  constructor(private http: HttpClient) { }  
      httpOptions = {  
        headers: new HttpHeaders({  
          'Content-Type': 'application/json'  
        })  
      }    
      getData(){  
        return this.http.get(this.rootURL + '/Pagamentos'); 
      }        
      postData(formData){  
        return this.http.post(this.rootURL + '/Pagamentos',formData);  
      }  
      putData(id,formData){  
        return this.http.put(this.rootURL + '/Pagamentos/'+id,formData);  
      }  

      deleteData(id){  
        return this.http.delete(this.rootURL + '/Pagamentos/'+id);  
      }  
}

Note que estamos definindo a url onde nossa API vai estar atendendo (verifique a porta) e o endpoint /Pagamentos.

Vamos abrir o arquivo app.module.ts e configurar o serviço criado, a definição do formulário e o http:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';  
import { HttpClientModule }    from '@angular/common/http';  
import { AppService } from './app.service';  
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule,  
    ReactiveFormsModule,  
    HttpClientModule  
  ],
  providers: [AppService],
  bootstrap: [AppComponent]
})
export class AppModule { }

Para invocar os métodos do serviço criado altere o código do arquivo app.component.ts :

import { Component } from '@angular/core';
import {AppService} from './app.service';  
import { FormGroup, FormControl,Validators } from '@angular/forms';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'PagamentoCartao';
  constructor(private AppService: AppService) { }  
  data: any;  
  CartaoForm: FormGroup;  
  submitted = false;   
  EventValue: any = "Salvar";    
  ngOnInit(): void {  
    this.getdata();    
    this.CartaoForm = new FormGroup({  
      PagamentoId: new FormControl(null),  
      NomeTitular: new FormControl("",[Validators.required]),        
      NumeroCartao: new FormControl("",[Validators.required]),  
      DataExpiracao:new FormControl("",[Validators.required]),  
      CVV: new FormControl("",[Validators.required]),  
    })    
  }  

  getdata() {  
    this.AppService.getData().subscribe((data: any[]) => {  
      this.data = data;  
    })  
  }  

  deleteData(id) {  
    this.AppService.deleteData(id).subscribe((data: any[]) => {  
      this.data = data;  
      this.getdata();  
    })  
  }  

  Save() {   
    this.submitted = true;      
     if (this.CartaoForm.invalid) {  
            return;  
     }  
    this.AppService.postData(this.CartaoForm.value).subscribe((data: any[]) => {  
      this.data = data;  
      this.resetFrom();   
    })  
  }  
  Update() {   
    this.submitted = true;      
    if (this.CartaoForm.invalid) {  
     return;  
    }        
    this.AppService.putData(this.CartaoForm.value.PagamentoId,
             this.CartaoForm.value).subscribe((data: any[]) => {  
      this.data = data;  
      this.resetFrom();  
    })  
  }  
  
  EditData(Data) {  
    this.CartaoForm.controls["PagamentoId"].setValue(Data.PagamentoId);  
    this.CartaoForm.controls["NomeTitular"].setValue(Data.NomeTitular);      
    this.CartaoForm.controls["NumeroCartao"].setValue(Data.NumeroCartao);  
    this.CartaoForm.controls["DataExpiracao"].setValue(Data.DataExpiracao);  
    this.CartaoForm.controls["CVV"].setValue(Data.CVV);  
    this.EventValue = "Atualizar";  
  }    
  resetFrom()  
  {     
    this.getdata();  
    this.CartaoForm.reset();  
    this.EventValue = "Salvar";  
    this.submitted = false;   
  } 
}

Agora vamos criar o formulário que será definido no arquivo app.component.html:

<div class="container">  
  <form [formGroup]="CartaoForm" (ngSubmit)="this[EventValue]()">  
      <h3>Cartão - Pagamentos</h3>  
      <div class="row">  
      <table class="table">  
      <tr>  
        <td>Nome do Titular</td>  
        <td>  
          <input type="hidden" formControlName="PagamentoId">  
          <input type="text" formControlName="NomeTitular">  
          <div *ngIf="submitted && CartaoForm.controls.NomeTitular.errors" class="text-danger">  
            <div *ngIf="CartaoForm.controls.NomeTitular.errors.required">O nome é obrigatório</div>  
          </div>   
        </td>  
      </tr>  
      <tr>  
        <td>Número do Cartão</td>  
        <td><input type="text" formControlName="NumeroCartao">  
          <div *ngIf="submitted && CartaoForm.controls.NumeroCartao.errors" class="text-danger">  
            <div *ngIf="CartaoForm.controls.NumeroCartao.errors.required">O número do cartão é obrigatório</div>  
          </div>   
        </td>  
      </tr>  
      <tr>  
        <td>Data de Expiração</td>  
        <td>  
          <input type="text" formControlName="DataExpiracao">  
          <div *ngIf="submitted && CartaoForm.controls.DataExpiracao.errors" class="text-danger">  
            <div *ngIf="CartaoForm.controls.DataExpiracao.errors.required">Informe a data de expiração</div>  
          </div>  
        </td>  
      </tr>  
      <tr>  
        <td>CVV</td>  
        <td>  
          <input type="text" formControlName="CVV">  
          <div *ngIf="submitted && CartaoForm.controls.CVV.errors" class="text-danger">  
            <div *ngIf="CartaoForm.controls.CVV.errors.required">O CVV é obrigatório</div>  
          </div>  
        </td>  
      </tr>  
      <tr>  
        <td colspan="2">  
          <button type="submit" class="btn btn-primary">{{EventValue}}</button>  
        </td>  
      </tr>  
    </table>  
    </div>  
   <div class="row">  
    <table class="table table-striped">  
      <tr>  
        <td>ID</td>  
        <td>Nome</td>  
        <td>No. Cartão</td>  
        <td>Data Expiração</td>  
        <td>CVV</td>  
        <td>Edita</td>  
        <td>Deleta</td>  
      </tr>  
      <tr *ngFor="let d of data">  
        <td>{{d.PagamentoId}}</td>  
        <td>{{d.NomeTitular}}</td>  
        <td>{{d.NumeroCartao}}</td>  
        <td>{{d.DataExpiracao}}</td>  
        <td>{{d.CVV}}</td>  
        <td><a (click)="EditData(d)" class="btn btn-warning">Edita</a></td>  
        <td><a (click)="deleteData(d.PagamentoId)" class="btn btn-danger">Deleta</a></td>    
      </tr>  
    </table>  
  </div>  
 </form>      
</div> 

Agora vamos criar o formulário. Abra o arquivo pagamento-detalhe.component.html e inclua o código abaixo:

<form #form="ngForm" autocomplete="off">
    <input type="hidden" name="PagamentoId" [value]="service.formData.PagamentoId">
    <div class="form-group">
      <div class="input-group">
        <div class="input-group-prepend">
          <div class="input-group-text bg-white">
            <i class="fas fa-user-circle" [class.green-icon]="NomeTitular.valid" [class.red-icon]="NomeTitular.invalid && NomeTitular.touched"></i>
          </div>
        </div>
        <input name="NomeTitular" #NomeTitular="ngModel" [(ngModel)]="service.formData.NomeTitular" class="form-control"
          placeholder="Nome do titular do Cartão" required>
      </div>
    </div>

    <div class="form-group">
      <div class="input-group">
        <div class="input-group-prepend">
          <div class="input-group-text bg-white">
            <i class="far fa-credit-card"  [class.green-icon]="NumeroCartao.valid" [class.red-icon]="NumeroCartao.invalid && NumeroCartao.touched"></i>
          </div>
        </div>
        <input name="NumeroCartao" #NumeroCartao="ngModel" [(ngModel)]="service.formData.NumeroCartao"
        class="form-control" placeholder="Número do Cartão de crédito" required maxlength="16" minlength="16">
      </div>
    </div>

    <div class="form-row">
      <div class="form-group col-md-7">
        <div class="input-group">
          <div class="input-group-prepend">
            <div class="input-group-text bg-white">
              <i class="fas fa-calendar-alt"  [class.green-icon]="DataExpiracao.valid" [class.red-icon]="DataExpiracao.invalid && DataExpiracao.touched"></i>
            </div>
          </div>
          <input name="DataExpiracao" #ExpirationDate="ngModel" [(ngModel)]="service.formData.DataExpiracao" class="form-control"
            placeholder="MM/YY" required maxlength="5" minlength="5">
        </div>
      </div>
      <div class="form-group col-md-5">
        <div class="input-group">
          <div class="input-group-prepend">
            <div class="input-group-text bg-white">
              <i class="fas fa-key"  [class.green-icon]="CVV.valid" [class.red-icon]="CVV.invalid && CVV.touched"></i>
            </div>
          </div>
          <input type="password" name="CVV" #CVV="ngModel" [(ngModel)]="service.formData.CVV" class="form-control" placeholder="CVV"
          required  maxlength="3" minlength="3">
        </div>
      </div>
    </div>

    <div class="form-group">
      <button class="btn btn-success btn-lg btn-block" type="submit" [disabled]="form.invalid"><i class="fas fa-database"></i> Submeter</button>
    </div>

  </form>

Executando o projeto neste momento com: ng serve

E acessando localhost:4200 veremos:

Para testar com a API basta você executar o projeto ASP .NET Core e a seguir executar o projeto Angular:

ng serve --o

Pegue os projetos aqui :   ApiCartao.zip e projeto Angular PagamentoCartao.zip (sem as referências)

Obs: Para restaurar os pacotes no projeto Angular digite o comando: npm install

"Levantarei os meus olhos para os montes, de onde vem o meu socorro.
O meu socorro vem do Senhor que fez o céu e a terra."

Salmos 121:1,2

Referências:


José Carlos Macoratti