Componentes en Angular
En el apartado anterior de la instalación vimos un primer acercamiento al nuestro componente principal app.component.
Pero ahora crearemos nuestros propios componentes de acuerdo para lo que se requiera.
Consumir APIS de la aplicación Cliente
En el caso de la Aplicación Cliente serian:
MostrarCliente
CrearCliente
ActualizarCliente
EliminarCliente
Resumen de Peticiones
Métodos | URL | Comportamiento |
---|---|---|
Get | localhost:8000/clientes | Mostrar todos los Clientes |
Get | localhost:8000/clientes/9 | Mostrar un cliente |
POST | localhost:8000/clientes/ | Crear un Cliente |
PATCH | localhost:8000/clientes/12 | Actualiza un Cliente |
DELETE | localhost:8000/clientes/12 | Elimina un Cliente |
Para llevar esto a Cabo recuerde que en el Proyecto de Django debe instalar un paquete llamado CORS, que es el encargado de permitir solicitudes a nuestra aplicación Django desde otros orígenes.
CORS en el BackEnd de Django
http://190.131.213.204:9090/site/backend/Django/cors/
CORS en el BackEnd de NodeJs
http://190.131.213.204:9090/site/backend/NodeJs/cors_nodejs/
Configurar el módulo de la aplicación
Abra src/app/app.module.ts
e importe FormsModule
:HttpClientModule
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/layouts/header/header.component';
import { ContentComponent } from './components/layouts/content/content.component';
import { FooterComponent } from './components/layouts/footer/footer.component';
import {MenubarModule} from 'primeng/menubar';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MostrarClienteComponent } from './components/cliente/mostrar-cliente/mostrar-cliente.component';
import { CrearClienteComponent } from './components/cliente/crear-cliente/crear-cliente.component';
import { ActualizarClienteComponent } from './components/cliente/actualizar-cliente/actualizar-cliente.component';
import { EliminarClienteComponent } from './components/cliente/eliminar-cliente/eliminar-cliente.component';
import { MostrarTipoProductoComponent } from './components/tipoProducto/mostrar-tipo-producto/mostrar-tipo-producto.component';
import { CrearTipoProductoComponent } from './components/tipoProducto/crear-tipo-producto/crear-tipo-producto.component';
import { ActualizarTipoProductoComponent } from './components/tipoProducto/actualizar-tipo-producto/actualizar-tipo-producto.component';
import { EliminarTipoProductoComponent } from './components/tipoProducto/eliminar-tipo-producto/eliminar-tipo-producto.component';
import { MostrarProductoComponent } from './components/producto/mostrar-producto/mostrar-producto.component';
import { CrearProductoComponent } from './components/producto/crear-producto/crear-producto.component';
import { ActualizarProductoComponent } from './components/producto/actualizar-producto/actualizar-producto.component';
import { EliminarProductoComponent } from './components/producto/eliminar-producto/eliminar-producto.component';
import { MostrarVentaComponent } from './components/venta/mostrar-venta/mostrar-venta.component';
import { CrearVentaComponent } from './components/venta/crear-venta/crear-venta.component';
import { ActualizarVentaComponent } from './components/venta/actualizar-venta/actualizar-venta.component';
import { EliminarVentaComponent } from './components/venta/eliminar-venta/eliminar-venta.component';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
ContentComponent,
FooterComponent,
MostrarClienteComponent,
CrearClienteComponent,
ActualizarClienteComponent,
EliminarClienteComponent,
MostrarTipoProductoComponent,
CrearTipoProductoComponent,
ActualizarTipoProductoComponent,
EliminarTipoProductoComponent,
MostrarProductoComponent,
CrearProductoComponent,
ActualizarProductoComponent,
EliminarProductoComponent,
MostrarVentaComponent,
CrearVentaComponent,
ActualizarVentaComponent,
EliminarVentaComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MenubarModule,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Crear servicio de datos para la aplicación de Clientes
Este servicio utilizará Angular HTTPClient
para enviar solicitudes HTTP.\
Puede ver que sus funciones incluyen operaciones CRUD y método de búsqueda.
Se crea un archivo que representa el modelo de Cliente
src/app/models/cliente.ts
export interface ClienteI {
id?: number;
nombreCliente: string
direccionCliente: string
telefonoCliente: string
correoCliente: string
passwordCliente: string
}
Para crear un servicio en la terminal de VS Code
Se crean automaticamente los archivos
Componentes CRUD Clientes
En el Servicio
En el archivo creado para el servicio en src/app/services/cliente.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ClienteI } from '../models/cliente';
@Injectable({
providedIn: 'root'
})
export class ClienteService {
api_uri_nodejs = 'http://localhost:8000';
api_uri_django = 'http://localhost:4000';
base_path = `${this.api_uri_nodejs}/clientes/`
constructor(
private http:HttpClient
) { }
getAllCliente():Observable<{cliente:ClienteI[]}>{
return this.http
.get<{cliente:ClienteI[]}>(this.base_path)
}
getOneCliente():Observable<{cliente:ClienteI[]}>{
return this.http
.get<{cliente:ClienteI[]}>(this.base_path)
}
createCliente(data: any):Observable<ClienteI>{
return this.http.post<ClienteI>(this.base_path, data)
}
updateCliente(id: number, data: any): Observable<ClienteI> {
return this.http.put<ClienteI>(`${this.base_path}/${id}`, data);
}
deleteCliente(id: number): Observable<ClienteI> {
return this.http.delete<ClienteI>(`${this.base_path}/${id}`);
}
}
En el Componente Mostrar Cliente
En el src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.ts
import { Component, OnInit } from '@angular/core';
import { ClienteI } from 'src/app/models/cliente';
import { Router } from '@angular/router';
import { ClienteService } from '../../../services/cliente.service'
@Component({
selector: 'app-mostrar-cliente',
templateUrl: './mostrar-cliente.component.html',
styleUrls: ['./mostrar-cliente.component.css']
})
export class MostrarClienteComponent implements OnInit {
public clientes:ClienteI[] = []
public displayedColumns: string[] = ["id", "nombreCliente", "direccionCliente", "telefonoCliente", "correoCliente","Acciones"]
constructor(
private clienteService: ClienteService,
private router: Router
) { }
ngOnInit(): void {
this.mostrarClientes()
}
mostrarClientes() {
this.clienteService.getAllCliente()
.subscribe({
next: (data) => {
this.clientes = data.clientes
console.log(this.clientes)
}
})
}
}
Nota
: Para que esto funcione, es necesario que el Backend (NodeJs o Django esten levantado el Servidor)
Como podemos observar, no muestra información, pero si le damos en el navegador Boton derecho >> Inspeccionar >> Console
Ya estamos accediendo a la información del Backend.
Para culminar el proceso nos dirigimos a:
src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.html
<p-table [value]="clientes">
<ng-template pTemplate="header">
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Direccion</th>
<th>Telefono</th>
<th>Correo</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-clientes>
<tr>
<td>{{clientes.id}}</td>
<td>{{clientes.nombreCliente}}</td>
<td>{{clientes.direccionCliente}}</td>
<td>{{clientes.telefonoCliente}}</td>
<td>{{clientes.correoCliente}}</td>
</tr>
</ng-template>
</p-table>
Entendiendo mejor este código
Importamos import {TableModule} from 'primeng/table'
Ya podemos ver la información proveniente del BackEnd
Agregando botones a las acciones de cada registro e importamos
import {ButtonModule} from 'primeng/button'
src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/layouts/header/header.component';
import { ContentComponent } from './components/layouts/content/content.component';
import { FooterComponent } from './components/layouts/footer/footer.component';
import {MenubarModule} from 'primeng/menubar';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MostrarClienteComponent } from './components/cliente/mostrar-cliente/mostrar-cliente.component';
import { CrearClienteComponent } from './components/cliente/crear-cliente/crear-cliente.component';
import { ActualizarClienteComponent } from './components/cliente/actualizar-cliente/actualizar-cliente.component';
import { EliminarClienteComponent } from './components/cliente/eliminar-cliente/eliminar-cliente.component';
import { MostrarTipoProductoComponent } from './components/tipoProducto/mostrar-tipo-producto/mostrar-tipo-producto.component';
import { CrearTipoProductoComponent } from './components/tipoProducto/crear-tipo-producto/crear-tipo-producto.component';
import { ActualizarTipoProductoComponent } from './components/tipoProducto/actualizar-tipo-producto/actualizar-tipo-producto.component';
import { EliminarTipoProductoComponent } from './components/tipoProducto/eliminar-tipo-producto/eliminar-tipo-producto.component';
import { MostrarProductoComponent } from './components/producto/mostrar-producto/mostrar-producto.component';
import { CrearProductoComponent } from './components/producto/crear-producto/crear-producto.component';
import { ActualizarProductoComponent } from './components/producto/actualizar-producto/actualizar-producto.component';
import { EliminarProductoComponent } from './components/producto/eliminar-producto/eliminar-producto.component';
import { MostrarVentaComponent } from './components/venta/mostrar-venta/mostrar-venta.component';
import { CrearVentaComponent } from './components/venta/crear-venta/crear-venta.component';
import { ActualizarVentaComponent } from './components/venta/actualizar-venta/actualizar-venta.component';
import { EliminarVentaComponent } from './components/venta/eliminar-venta/eliminar-venta.component';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import {TableModule} from 'primeng/table';
import {ButtonModule} from 'primeng/button';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
ContentComponent,
FooterComponent,
MostrarClienteComponent,
CrearClienteComponent,
ActualizarClienteComponent,
EliminarClienteComponent,
MostrarTipoProductoComponent,
CrearTipoProductoComponent,
ActualizarTipoProductoComponent,
EliminarTipoProductoComponent,
MostrarProductoComponent,
CrearProductoComponent,
ActualizarProductoComponent,
EliminarProductoComponent,
MostrarVentaComponent,
CrearVentaComponent,
ActualizarVentaComponent,
EliminarVentaComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MenubarModule,
FormsModule,
HttpClientModule,
TableModule,
ButtonModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Y colocamos nuestros botones en las acciones de los registros
src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.html
<p-table [value]="clientes">
<ng-template pTemplate="header">
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Direccion</th>
<th>Telefono</th>
<th>Correo</th>
<th>Acciones</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-clientes>
<tr>
<td>{{clientes.id}}</td>
<td>{{clientes.nombreCliente}}</td>
<td>{{clientes.direccionCliente}}</td>
<td>{{clientes.telefonoCliente}}</td>
<td>{{clientes.correoCliente}}</td>
<td>
<p-button icon="pi pi-print" class="mr-1"></p-button>
<p-button icon="pi pi-sync" class="mx-1"></p-button>
<p-button icon="pi pi-eraser" class="mx-1"></p-button>
</td>
</tr>
</ng-template>
</p-table>
Y se muestra así:
Ahora colocamos nuestro botón de crear Clientes en la parte superior de la tabla de registros, en el componente MostrarCliente. Adicionalmente borramos el contenido del componente Content.
src/app/layouts/content/content.component.html
Ajustamos el css del header y el section de app.component
src/app/app.component.css
*{
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
main {
display: grid;
gap: 10px;
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
grid-template-areas:
"header header header header header"
"section section section section section"
"footer footer footer footer footer";
row-gap: 0;
column-gap: 0;
grid-template-rows: 14% 76% 10%;
height: 98vh;
}
header {
grid-area: header;
/* border: 1px solid royalblue; */
background-color: #8DC3D8;
margin-top: 0.1em;
margin-left: 0.5em;
margin-right: 1.5em;
}
section {
grid-area: section;
margin-top: 1em;
margin-left: 0.2em;
margin-right: 1em;
/* border: 1px solid royalblue; */
}
footer {
grid-area: footer;
/* border: 1px solid royalblue; */
}
Luego, agregamos el botón Crear Cliente en la parte superior del Componente Mostrar Cliente.
src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.html
<div class="flex align-items-center justify-content-end bg-cyan-100">
<a
pButton
pRipple
label="Crear Clientes"
icon="pi pi-user-plus"
class="bg-cyan-600"
[routerLink]="['/addclientes']">
</a>
</div>
<p-table [value]="clientes">
<ng-template pTemplate="header">
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Direccion</th>
<th>Telefono</th>
<th>Correo</th>
<th>Acciones</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-clientes>
<tr>
<td>{{clientes.id}}</td>
<td>{{clientes.nombreCliente}}</td>
<td>{{clientes.direccionCliente}}</td>
<td>{{clientes.telefonoCliente}}</td>
<td>{{clientes.correoCliente}}</td>
<td>
<button
pButton
pRipple
icon="pi pi-print"
class="bg-cyan-600 mr-1"
</button>
<a
pButton
pRipple
icon="pi pi-sync"
class="bg-cyan-600 mr-1"
</a>
<button
type="button"
pButton
pRipple
icon="pi pi-eraser"
class="bg-cyan-600 mr-1"
</button>
</td>
</tr>
</ng-template>
</p-table>
Salida en el navegador:
Complementamos con los estilos .css en el archivo
src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.css
Ahora, si presionamos el botón Crear Clientes, muestra el componente Crear Clientes.
Lo que quiere decir que podemos dirigirnos al componente Crear Clientes en el archivo .html y crear el formulario para crear los clientes.
src/app/components/cliente/crear-cliente/crear-cliente.component.html
src/app/components/cliente/crear-cliente/crear-cliente.component.ts
Importar ReactiveFormsModule
en src/app/app.mudule.ts
En el Componente Crear Cliente
En el src/app/components/cliente/crear-cliente/crear-cliente.component.html
<form [formGroup]="form" novalidate (ngSubmit)="onSubmit()" class="p-3 bg-faded">
<div class="grid">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1">
<span class="p-inputgroup-addon"><i class="pi pi-user"></i></span>
<input type="text" pInputText formControlName="nombreCliente" placeholder="nombreCliente" title="nombreCliente">
</div>
</div>
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-wallet"></i></span>
<input type="text" pInputText formControlName="direccionCliente" placeholder="direccionCliente" title="direccionCliente" >
</div>
</div>
</div>
<div class="grid">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1">
<span class="p-inputgroup-addon"><i class="pi pi-phone"></i></span>
<input type="text" pInputText formControlName="telefonoCliente" placeholder="telefonoCliente" title="telefonoCliente">
</div>
</div>
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-bookmark"></i></span>
<input type="email" pInputText formControlName="correoCliente" placeholder="correoCliente" title="correoCliente" >
</div>
</div>
</div>
<div class="text-right">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-comments"></i></span>
<input type="password" pInputText formControlName="passwordCliente" placeholder="passwordCliente" title="passwordCliente" >
</div>
<button pButton pRipple type="submit" icon="pi pi-check" label="Enviar"
[disabled]="!form.valid" class="mt-4 mr-2">
</button>
<button pButton pRipple type="button" icon="pi pi-times" label="Cancelar"
class=" mr-2" (click)="cancel()">
</button>
</div>
</div>
</form>
En el src/app/components/cliente/crear-cliente/crear-cliente.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { ClienteService } from 'src/app/services/cliente.service';
import { ClienteI } from 'src/app/models/cliente';
@Component({
selector: 'app-crear-cliente',
templateUrl: './crear-cliente.component.html',
styleUrls: ['./crear-cliente.component.css']
})
export class CrearClienteComponent implements OnInit {
public form:FormGroup=this.formBuilder.group({
nombreCliente: ['', [Validators.required]],
direccionCliente: ['', [Validators.required]],
telefonoCliente: ['', [Validators.required]],
correoCliente: ['', [Validators.required]],
passwordCliente: ['', [Validators.required]],
});
constructor(
private formBuilder: FormBuilder,
private clienteService: ClienteService,
private router: Router,
) { }
ngOnInit(): void {
}
onSubmit(): void {
const formValue: ClienteI = this.form.value;
console.log(formValue);
this.clienteService.createCliente(formValue).subscribe(
() => {
// console.log('Se ha creado correctamente');
this.router.navigateByUrl('clientes');
},
err => {
console.log(err);
console.log('No se ha creado correctamente');
}
);
}
cancel() {
this.router.navigateByUrl('/clientes');
}
get nombreCliente() { return this.form.get('nombreCliente'); }
get direccionCliente() { return this.form.get('direccionCliente'); }
get telefonoCliente() { return this.form.get('telefonoCliente'); }
get correoCliente() { return this.form.get('correoCliente'); }
get passwordCliente() { return this.form.get('passwordCliente'); }
}
Tener incluido los módulos en imports:
FormsModule,
ReactiveFormsModule,
En el src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/layouts/header/header.component';
import { ContentComponent } from './components/layouts/content/content.component';
import { FooterComponent } from './components/layouts/footer/footer.component';
import {MenubarModule} from 'primeng/menubar';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MostrarClienteComponent } from './components/cliente/mostrar-cliente/mostrar-cliente.component';
import { CrearClienteComponent } from './components/cliente/crear-cliente/crear-cliente.component';
import { ActualizarClienteComponent } from './components/cliente/actualizar-cliente/actualizar-cliente.component';
import { EliminarClienteComponent } from './components/cliente/eliminar-cliente/eliminar-cliente.component';
import { MostrarTipoProductoComponent } from './components/tipoProducto/mostrar-tipo-producto/mostrar-tipo-producto.component';
import { CrearTipoProductoComponent } from './components/tipoProducto/crear-tipo-producto/crear-tipo-producto.component';
import { ActualizarTipoProductoComponent } from './components/tipoProducto/actualizar-tipo-producto/actualizar-tipo-producto.component';
import { EliminarTipoProductoComponent } from './components/tipoProducto/eliminar-tipo-producto/eliminar-tipo-producto.component';
import { MostrarProductoComponent } from './components/producto/mostrar-producto/mostrar-producto.component';
import { CrearProductoComponent } from './components/producto/crear-producto/crear-producto.component';
import { ActualizarProductoComponent } from './components/producto/actualizar-producto/actualizar-producto.component';
import { EliminarProductoComponent } from './components/producto/eliminar-producto/eliminar-producto.component';
import { MostrarVentaComponent } from './components/venta/mostrar-venta/mostrar-venta.component';
import { CrearVentaComponent } from './components/venta/crear-venta/crear-venta.component';
import { ActualizarVentaComponent } from './components/venta/actualizar-venta/actualizar-venta.component';
import { EliminarVentaComponent } from './components/venta/eliminar-venta/eliminar-venta.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import {TableModule} from 'primeng/table';
import {ButtonModule} from 'primeng/button';
import {InputTextModule} from 'primeng/inputtext';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
ContentComponent,
FooterComponent,
MostrarClienteComponent,
CrearClienteComponent,
ActualizarClienteComponent,
EliminarClienteComponent,
MostrarTipoProductoComponent,
CrearTipoProductoComponent,
ActualizarTipoProductoComponent,
EliminarTipoProductoComponent,
MostrarProductoComponent,
CrearProductoComponent,
ActualizarProductoComponent,
EliminarProductoComponent,
MostrarVentaComponent,
CrearVentaComponent,
ActualizarVentaComponent,
EliminarVentaComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MenubarModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
TableModule,
ButtonModule,
InputTextModule,
],
providers: [
],
bootstrap: [AppComponent]
})
export class AppModule { }
Activar Mensajes Emergentes
Dirigirse a la ayuda de PrimeNg
https://www.primefaces.org/primeng/toast
En primer lugar incluir import {ToastModule} from 'primeng/toast';
y en Prividers MessageService
en el archivo src/app/app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/layouts/header/header.component';
import { ContentComponent } from './components/layouts/content/content.component';
import { FooterComponent } from './components/layouts/footer/footer.component';
import {MenubarModule} from 'primeng/menubar';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MostrarClienteComponent } from './components/cliente/mostrar-cliente/mostrar-cliente.component';
import { CrearClienteComponent } from './components/cliente/crear-cliente/crear-cliente.component';
import { ActualizarClienteComponent } from './components/cliente/actualizar-cliente/actualizar-cliente.component';
import { EliminarClienteComponent } from './components/cliente/eliminar-cliente/eliminar-cliente.component';
import { MostrarTipoProductoComponent } from './components/tipoProducto/mostrar-tipo-producto/mostrar-tipo-producto.component';
import { CrearTipoProductoComponent } from './components/tipoProducto/crear-tipo-producto/crear-tipo-producto.component';
import { ActualizarTipoProductoComponent } from './components/tipoProducto/actualizar-tipo-producto/actualizar-tipo-producto.component';
import { EliminarTipoProductoComponent } from './components/tipoProducto/eliminar-tipo-producto/eliminar-tipo-producto.component';
import { MostrarProductoComponent } from './components/producto/mostrar-producto/mostrar-producto.component';
import { CrearProductoComponent } from './components/producto/crear-producto/crear-producto.component';
import { ActualizarProductoComponent } from './components/producto/actualizar-producto/actualizar-producto.component';
import { EliminarProductoComponent } from './components/producto/eliminar-producto/eliminar-producto.component';
import { MostrarVentaComponent } from './components/venta/mostrar-venta/mostrar-venta.component';
import { CrearVentaComponent } from './components/venta/crear-venta/crear-venta.component';
import { ActualizarVentaComponent } from './components/venta/actualizar-venta/actualizar-venta.component';
import { EliminarVentaComponent } from './components/venta/eliminar-venta/eliminar-venta.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import {TableModule} from 'primeng/table';
import {ButtonModule} from 'primeng/button';
import {InputTextModule} from 'primeng/inputtext';
import {ToastModule} from 'primeng/toast';
import { MessageService } from 'primeng/api';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
ContentComponent,
FooterComponent,
MostrarClienteComponent,
CrearClienteComponent,
ActualizarClienteComponent,
EliminarClienteComponent,
MostrarTipoProductoComponent,
CrearTipoProductoComponent,
ActualizarTipoProductoComponent,
EliminarTipoProductoComponent,
MostrarProductoComponent,
CrearProductoComponent,
ActualizarProductoComponent,
EliminarProductoComponent,
MostrarVentaComponent,
CrearVentaComponent,
ActualizarVentaComponent,
EliminarVentaComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MenubarModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule,
TableModule,
ButtonModule,
InputTextModule,
ToastModule
],
providers: [
MessageService
],
bootstrap: [AppComponent]
})
export class AppModule { }
Visualizando y entendiendo el código anterior
\
Luego lo incluyo en html y el ts de crear cliente, así:
src/app/components/cliente/crear-cliente/crear-cliente.component.html
<div>
<p-toast></p-toast>
</div>
<form [formGroup]="form" novalidate (ngSubmit)="onSubmit()" class="p-3 bg-faded">
<div class="grid">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1">
<span class="p-inputgroup-addon"><i class="pi pi-user"></i></span>
<input type="text" pInputText formControlName="nombreCliente" placeholder="nombreCliente" title="nombreCliente">
</div>
</div>
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-wallet"></i></span>
<input type="text" pInputText formControlName="direccionCliente" placeholder="direccionCliente" title="direccionCliente" >
</div>
</div>
</div>
<div class="grid">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1">
<span class="p-inputgroup-addon"><i class="pi pi-phone"></i></span>
<input type="text" pInputText formControlName="telefonoCliente" placeholder="telefonoCliente" title="telefonoCliente">
</div>
</div>
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-bookmark"></i></span>
<input type="email" pInputText formControlName="correoCliente" placeholder="correoCliente" title="correoCliente" >
</div>
</div>
</div>
<div class="text-right">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-comments"></i></span>
<input type="password" pInputText formControlName="passwordCliente" placeholder="passwordCliente" title="passwordCliente" >
</div>
<button pButton pRipple type="submit" icon="pi pi-check" label="Enviar"
[disabled]="!form.valid" class="mt-4 mr-2">
</button>
<button pButton pRipple type="button" icon="pi pi-times" label="Cancelar"
class=" mr-2" (click)="cancel()">
</button>
</div>
</div>
</form>
src/app/components/cliente/crear-cliente/crear-cliente.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { ClienteService } from 'src/app/services/cliente.service';
import { ClienteI } from 'src/app/models/cliente';
import {Message,MessageService} from 'primeng/api';
@Component({
selector: 'app-crear-cliente',
templateUrl: './crear-cliente.component.html',
styleUrls: ['./crear-cliente.component.css']
})
export class CrearClienteComponent implements OnInit {
public form:FormGroup=this.formBuilder.group({
nombreCliente: ['', [Validators.required]],
direccionCliente: ['', [Validators.required]],
telefonoCliente: ['', [Validators.required]],
correoCliente: ['', [Validators.required]],
passwordCliente: ['', [Validators.required]],
});
constructor(
private formBuilder: FormBuilder,
private clienteService: ClienteService,
private messageService: MessageService,
private router: Router,
) { }
ngOnInit(): void {
}
onSubmit(): void {
const formValue: ClienteI = this.form.value;
console.log(formValue);
this.clienteService.createCliente(formValue).subscribe(
() => {
// console.log('Se ha creado correctamente');
setTimeout(()=>{
this.messageService.add({severity:'success', summary: 'Notificación', detail: 'Cliente Creado', life:5000});
}, 0);
this.router.navigateByUrl('clientes');
},
err => {
console.log(err);
console.log('No se ha creado correctamente');
}
);
}
cancel() {
this.router.navigateByUrl('/clientes');
}
get nombreCliente() { return this.form.get('nombreCliente'); }
get direccionCliente() { return this.form.get('direccionCliente'); }
get telefonoCliente() { return this.form.get('telefonoCliente'); }
get correoCliente() { return this.form.get('correoCliente'); }
get passwordCliente() { return this.form.get('passwordCliente'); }
}
En el Componente Eliminar Cliente
src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.html
<div class="flex align-items-center justify-content-end bg-cyan-100">
<a
pButton
pRipple
label="Crear Clientes"
icon="pi pi-user-plus"
class="bg-cyan-600"
[routerLink]="['/addclientes']"></a>
</div>
<div>
<p-toast></p-toast>
</div>
<p-table [value]="clientes">
<ng-template pTemplate="header">
<tr>
<th>ID</th>
<th>Nombre</th>
<th>Direccion</th>
<th>Telefono</th>
<th>Correo</th>
<th>Acciones</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-clientes>
<tr>
<td>{{clientes.id}}</td>
<td>{{clientes.nombreCliente}}</td>
<td>{{clientes.direccionCliente}}</td>
<td>{{clientes.telefonoCliente}}</td>
<td>{{clientes.correoCliente}}</td>
<td>
<button
pButton
pRipple
icon="pi pi-print"
class="bg-cyan-600 mr-1"
(click)="imprimir(clientes.id)">
</button>
<a
pButton
pRipple
icon="pi pi-sync"
class="bg-cyan-600 mr-1"
[routerLink]="['/clientes/edit', clientes.id]">
</a>
<button
type="button"
pButton
pRipple
icon="pi pi-eraser"
class="bg-cyan-600 mr-1"
(click)="eliminar(clientes.id)">
</button>
</td>
</tr>
</ng-template>
</p-table>
src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.ts
import { Component, OnInit } from '@angular/core';
import { ClienteI } from 'src/app/models/cliente';
import { Router } from '@angular/router';
import { ClienteService } from '../../../services/cliente.service'
import {Message,MessageService} from 'primeng/api';
@Component({
selector: 'app-mostrar-cliente',
templateUrl: './mostrar-cliente.component.html',
styleUrls: ['./mostrar-cliente.component.css'],
})
export class MostrarClienteComponent implements OnInit {
public clientes:ClienteI[] = []
public msgs1: Message[]=[];
constructor(
private clienteService: ClienteService,
private router: Router,
private messageService: MessageService
) { }
ngOnInit(): void {
this.mostrarClientes()
}
mostrarClientes() {
this.clienteService.getAllCliente()
.subscribe({
next: (data) => {
this.clientes = data.clientes
// console.log(this.clientes)
}
})
}
eliminar(id: number): void{
this.router.navigateByUrl('/clientes');
this.clienteService.deleteCliente(id).subscribe(
() => {
this.messageService.add({severity:'warn', summary: 'Notificación', detail: 'Cliente Eliminado', life:5000});
this.mostrarClientes();
},
err => {
console.log('error')
this.router.navigateByUrl('/clientes');
}
);
}
imprimir(id: number){
}
}
En el Componente Actualizar Cliente
Verificar que en el boton de eliminar en el archivo del componente mostrar cliente: src/app/components/cliente/mostrar-cliente/mostrar-cliente.component.html
coincida con la ruta de app routing: src/app/app-routing.module.ts
Si esto funciona al presionar clic sobre el botón actualizar debe mostrar lo siguiente:
Ahora si, nos dirigimos a src/app/components/cliente/actualizar-cliente/actualizar-cliente.component.html
<form [formGroup]="form" novalidate (ngSubmit)="onSubmit()" class="p-3 bg-faded">
<div class="grid">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1">
<span class="p-inputgroup-addon"><i class="pi pi-user"></i></span>
<input type="text" pInputText formControlName="nombreCliente" placeholder="nombreCliente" title="nombreCliente">
</div>
</div>
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-wallet"></i></span>
<input type="text" pInputText formControlName="direccionCliente" placeholder="direccionCliente" title="direccionCliente" >
</div>
</div>
</div>
<div class="grid">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1">
<span class="p-inputgroup-addon"><i class="pi pi-phone"></i></span>
<input type="text" pInputText formControlName="telefonoCliente" placeholder="telefonoCliente" title="telefonoCliente">
</div>
</div>
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-bookmark"></i></span>
<input type="email" pInputText formControlName="correoCliente" placeholder="correoCliente" title="correoCliente" >
</div>
</div>
</div>
<div class="text-right">
<div class="col-12 sm:col-6">
<div class="p-inputgroup mb-1 ">
<span class="p-inputgroup-addon"><i class="pi pi-comments"></i></span>
<input type="password" pInputText formControlName="passwordCliente" placeholder="passwordCliente" title="passwordCliente" >
</div>
<button pButton pRipple type="submit" icon="pi pi-check" label="Enviar"
[disabled]="!form.valid" class="mt-4 mr-2">
</button>
<button pButton pRipple type="button" icon="pi pi-times" label="Cancelar"
class=" mr-2" (click)="cancel()">
</button>
</div>
</div>
</form>
src/app/components/cliente/actualizar-cliente/actualizar-cliente.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { ClienteService } from 'src/app/services/cliente.service';
import { ClienteI } from 'src/app/models/cliente';
import {Message,MessageService} from 'primeng/api';
@Component({
selector: 'app-actualizar-cliente',
templateUrl: './actualizar-cliente.component.html',
styleUrls: ['./actualizar-cliente.component.css']
})
export class ActualizarClienteComponent implements OnInit {
public id: number =0;
public form:FormGroup=this.formBuilder.group({
id: [''],
nombreCliente: ['', [Validators.required]],
direccionCliente: ['', [Validators.required]],
telefonoCliente: ['', [Validators.required]],
correoCliente: ['', [Validators.required]],
passwordCliente: ['', [Validators.required]],
});
constructor(
private formBuilder: FormBuilder,
private clienteService: ClienteService,
private messageService: MessageService,
private router: Router,
private route: ActivatedRoute,
) { }
ngOnInit(): void {
this.id = this.route.snapshot.params['id'];
// let idCliente = this.route.snapshot.paramMap.get("id");
this.getCliente(this.id);
}
getCliente(id: number){
this.clienteService.getOneCliente(id)
.subscribe({
next: (data) => {
this.form.setValue(data.cliente)
// console.log(data.cliente)
}
})
}
onSubmit(): void {
const formValue: ClienteI = this.form.value;
const id: number = this.form.value.id
this.clienteService.updateCliente(id, formValue).subscribe(
() => {
// console.log('Se ha creado correctamente');
setTimeout(()=>{
this.messageService.add({severity:'success', summary: 'Notificación', detail: 'Cliente Actualizado', life:5000});
}, 0);
this.router.navigateByUrl('clientes');
},
err => {
console.log(err);
console.log('No se ha creado correctamente');
}
);
}
cancel() {
this.router.navigateByUrl('/clientes');
}
get nombreCliente() { return this.form.get('nombreCliente'); }
get direccionCliente() { return this.form.get('direccionCliente'); }
get telefonoCliente() { return this.form.get('telefonoCliente'); }
get correoCliente() { return this.form.get('correoCliente'); }
get passwordCliente() { return this.form.get('passwordCliente'); }
}
Es importante verificar Frontend y BackEnd:
En el FrontEnd
El método getCliente en src/app/components/cliente/actualizar-cliente/actualizar-cliente.component.ts
En el método del servicio de clientes en src/app/services/cliente.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { ClienteI } from '../models/cliente';
@Injectable({
providedIn: 'root'
})
export class ClienteService {
api_uri_nodejs = 'http://localhost:4000';
api_uri_django = 'http://localhost:8000';
base_path = `${this.api_uri_django}/clientes/`
constructor(
private http:HttpClient
) {}
getAllCliente():Observable<{clientes:ClienteI[]}>{
return this.http
.get<{clientes:ClienteI[]}>(this.base_path)
}
getOneCliente(id: number):Observable<{cliente:ClienteI[]}>{
return this.http
.get<{cliente:ClienteI[]}>(`${this.base_path}${id}`)
}
createCliente(data: any):Observable<ClienteI>{
return this.http.post<ClienteI>(this.base_path, data)
}
updateCliente(id: number, data: ClienteI): Observable<ClienteI> {
return this.http.put<ClienteI>(`${this.base_path}${id}`, data);
}
deleteCliente(id: number): Observable<ClienteI> {
return this.http.delete<ClienteI>(`${this.base_path}${id}`);
}
}
En el BackEnd NodeJs
En el BackEnd Django