Contenido del curso
Fundamentos de unit testing en Angular
Testing en servicios
Proyecto
Testing en consultas HTTP
Bonus
Próximos pasos
Product Service Http
Contenido del curso
Product Service Http
Cesar Elías Armendariz Ruano
EstudianteFranco Amoroso
EstudianteBrayam Esteban Quiñones Sanchez
EstudianteJorge Luis Silva Medina
EstudianteVíctor Rolack
EstudianteSebastian Collantes
EstudianteKevin Bueno
EstudianteJose Armando Acevedo Angarita
EstudianteJosue Vargas
EstudianteJuan Felipe Vallejo Orozco
EstudianteDanny Alejandro fernandez gallego
EstudianteVictor Alfredo Matzar Say
EstudianteJoel Osvaldo Santos Soto
EstudianteEl product component se conectara a un servicio que hara llamadas a una API real de la siguiente manera
primero utilizaremos modelos y servicios de otro proyecto de la escuela de angular angular-router en la rama de producción donde buscaremos dentro de la carpeta src/app/models todos los modelos y los copiaremos al proyecto de testing con la misma ruta
Posteriormente haremos lo mismo con el servicio de products que estara en la ruta src/app/services/products.service.ts con los siguientes cambios
products.service.ts
import { Injectable } from '@angular/core'; import { HttpClient, HttpParams, HttpErrorResponse, HttpStatusCode } from '@angular/common/http'; import { retry, catchError, map } from 'rxjs/operators'; import { throwError, zip } from 'rxjs'; import { Product, CreateProductDTO, UpdateProductDTO } from './../models/product.model'; import { environment } from './../../environments/environment'; @Injectable({ providedIn: 'root' }) export class ProductsService { private apiUrl = `${environment.API_URL}/api/v1`; constructor( private http: HttpClient ) { } getByCategory(categoryId: string, limit?: number, offset?: number){ let params = new HttpParams(); if (limit && offset != null) { params = params.set('limit', limit); params = params.set('offset', offset); } return this.http.get<Product[]>(`${this.apiUrl}/categories/${categoryId}/products`, { params }) } getAllSimple() { return this.http.get<Product[]>(`${this.apiUrl}/products`); } getAll(limit?: number, offset?: number) { let params = new HttpParams(); if (limit && offset != null) { params = params.set('limit', limit); params = params.set('offset', offset); } return this.http.get<Product[]>(`${this.apiUrl}/products`, { params }) .pipe( retry(3), map(products => products.map(item => { return { ...item, taxes: .19 * item.price } })) ); } fetchReadAndUpdate(id: string, dto: UpdateProductDTO) { return zip( this.getOne(id), this.update(id, dto) ); } getOne(id: string) { return this.http.get<Product>(`${this.apiUrl}/products/${id}`) .pipe( catchError((error: HttpErrorResponse) => { if (error.status === HttpStatusCode.Conflict) { return throwError('Algo esta fallando en el server'); } if (error.status === HttpStatusCode.NotFound) { return throwError('El producto no existe'); } if (error.status === HttpStatusCode.Unauthorized) { return throwError('No estas permitido'); } return throwError('Ups algo salio mal'); }) ) } create(dto: CreateProductDTO) { return this.http.post<Product>(`${this.apiUrl}/products`, dto); } update(id: string, dto: UpdateProductDTO) { return this.http.put<Product>(`${this.apiUrl}/products/${id}`, dto); } delete(id: string) { return this.http.delete<boolean>(`${this.apiUrl}/products/${id}`); } }
posteriormente haremos cambios a nuestros environments del proyecto para conectar con la API
environments.prod.ts
export const environment = { production: true, API_URL: 'https://api.escuelajs.co' };
environments.ts
export const environment = { production: false, API_URL: 'https://api.escuelajs.co' };
posteriormente haremos una inyección de dependencia en nuestro product component
product.component.ts
import { Component, OnInit } from '@angular/core'; import { Product } from './../../models/product.model'; import { ProductsService } from './../../services/product.service'; export class ProductsComponent implements OnInit { products: Product[] = []; constructor( private productsService: ProductsService ) { } ngOnInit(): void { this.getAllProducts(); } getAllProducts() { this.productsService.getAllSimple() .subscribe(products => { this.products = products; }); } }
finalmente estilizaremos en product component html y scss
product.component.html
<section class="container"> <h2>Products Component</h2> <div class="my-grid"> <figure *ngFor="let product of products"> <img [src]="product.images[0]" alt=""> <figcaption> {{product.title}} - {{product.price}} </figcaption> </figure> </div> </section>
product.component.scss
.my-grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: auto; grid-gap: 15px }
Si no tienen la carpeta de environments
ng generate environments
Mas info en su documentacion Angular Build
Alguien sabe como hizo el profe para tener el autocompletado dentro del html??
Debe tener una AI de autocomplete ó una extensión de snippets. La mas básica es emmet para el html
Debe de ser la extension de vscode Angular Language Service
No me toma los estilos de picocss
Mi aporte
Enviroment
export const environment = { production: false, API_URL: 'https://api.escuelajs.co', };
my-grid
.my-grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: auto; grid-gap: 15px; }
Product html
<section class="container"> <h2>Product component</h2> <div class="my-grid"> <figure *ngFor="let p of products"> <img [src]="p.images[0]"> <figcaption> {{ p.title }} - {{ p.price }} </figcaption> </figure> </div> </section>
product ts
export class ProductsComponent implements OnInit { products: Product[] = []; constructor(private productService: ProductsService) { } ngOnInit(): void { this.getAllProducts(); } getAllProducts() { this.productService.getAllSimple().subscribe( r => { this.products = r; } ) } }
El servicio no funciona :(
Para visualizar la documentacion recuerden colocar /docs al final. https://api.escuelajs.co/docs/
A mi no me estaba funcionando el repositorio de imágenes que traía la Api, ya que es algo solo visual lo cambie de esta manera usando una Api que trae imágenes aleatorias:
<img [src]="product.images[0]" alt="">
Después
<img src="https://picsum.photos/id/{{product.id}}/400/?blur" alt="">
Para las llamadas a los productos la url de la api es :
api/v1/products
Algunos endpoints de la api no funcionan, pero /products y /categories si funcionan. Espero que durante el curso no hagamos una petición a un endpoint que no funcione :(
Hola a todos , alguien sabe cual es preferible a usar y por que ?
import { Product } from 'src/models/product.model';
import { Product } from '../../product.model';