Actividad entregable
7. Alta y Eliminación de Productos
7.1. Preparar el ProductService
Vamos a convertir ProductService en el centro del estado de la aplicación.
Es decir, será el responsable de almacenar la lista de productos, añadir nuevos y eliminar los existentes. Es necesario para que todos los componentes tengan la lista actualizada y la pantalla se refresque automáticamente,
BehaviorSubject es el corazón de nuestra aplicación. Es donde vive la lista de productos, y cada vez que la modificamos (añadiendo, eliminando o filtrando) la aplicación entera se actualiza automáticamente.
BehaviorSubject = es como una mini-base-de-datos dentro del servicio
Abrimos product.service.ts y añadimos BehaviorSubject:
import { BehaviorSubject } from 'rxjs';
Debajo del url:
private productosSubject = new
BehaviorSubject<Product[]>([]);productos$ =
this.productosSubject.asObservable();
private productosOriginales: Product[] = [];
private productosSubject = new BehaviorSubject<Product[]>([]);
productos$ = this.productosSubject.asObservable();
private productosOriginales: Product[] = [];
productosOriginales será nuestra lista interna.
productos$ es un observable que enviará los cambios a los componentes automáticamente.
Esto es esencial para que, cuando creemos o eliminemos un producto, la lista se actualice sola.
Modificar cargarProductos() para usar BehaviorSubject
Cuando llegan los productos desde la API, los guardamos internamente y los notificamos a toda la aplicación mediante next().
Reemplaza cargarProductos():
cargarProductos() {
this.http.get<Product[]>(this.url).subscribe({
next: (productos) => { this.productosOriginales =
productos;
this.productosSubject.next(productos);
}, error: (err) => console.error('Error al cargar
productos:', err) });}
cargarProductos() {
this.http.get<Product[]>(this.url).subscribe({
next: (productos) => {
this.productosOriginales = productos;
this.productosSubject.next(productos);
},
error: (err) => console.error('Error al cargar productos:', err)
});
}
Implementar agregarProducto()
Aquí viene algo importante, en un proyecto real, el ID del producto lo genera el backend cuando hacemos un POST.
Pero nuestra API solo permite lectura, no creación y Angular no tiene forma de pedir un ID nuevo al servidor.
Por eso podemos usar UUID. Es una pequeña ‘trampilla’ que sirve para simular el comportamiento real de un backend y poder añadir, identificar y eliminar productos correctamente.
Las versiones modernas de JavaScript incluyen crypto.randomUUID(), que nos genera un ID único automáticamente.
_id: crypto.randomUUID(), // la “trampilla”
Quedaría así:
agregarProducto(datos: any) {
const nuevoProducto: Product = { _id: crypto.randomUUID(), // Generamos un ID único (trampilla) name: datos.name, description: datos.description, price: datos.price, category: datos.category, image: datos.image, active: datos.active };
// Añadimos el nuevo producto al principio de la lista this.productosOriginales = [nuevoProducto, ...this.productosOriginales];
// Emitimos la nueva lista para que Angular actualice la vista this.productosSubject.next(this.productosOriginales);}
agregarProducto(datos: any) {
const nuevoProducto: Product = {
_id: crypto.randomUUID(), // Generamos un ID único (trampilla)
name: datos.name,
description: datos.description,
price: datos.price,
category: datos.category,
image: datos.image,
active: datos.active
};
// Añadimos el nuevo producto al principio de la lista
this.productosOriginales = [nuevoProducto, ...this.productosOriginales];
// Emitimos la nueva lista para que Angular actualice la vista
this.productosSubject.next(this.productosOriginales);
}
Implementar eliminarProducto()
Eliminar un producto es tan simple como filtrar la lista interna y volver a emitir el cambio. Angular actualizará automáticamente la pantalla.
Añadir al servicio:
eliminarProducto(id: string) {
this.productosOriginales = this.productosOriginales.filter(p => p._id !== id);
this.productosSubject.next(this.productosOriginales);
}