Horacio Castillejo
:)
Nicolas Molina
Profesor😀
Luis Gomero
😀
¿Cómo mejorar la selección de categorías en un formulario con Angular?
Cuando diseñamos formularios para aplicaciones web, la experiencia del usuario es primordial. Utilizar un select dinámico es una excelente estrategia, ya que permite cargar opciones directamente desde un API, dándole al usuario el control de las opciones que puede crear y seleccionar. En este contexto, te mostraré cómo integrar un select usando Angular y Angular Material para mejorar la operación de selección en un formulario.
¿Cómo integrar un select de Angular Material?
Implementar un select dinámico en Angular utilizando Angular Material mejora la interacción al proporcionar un UI más amigable y con mayor integridad. Aquí te muestro cómo hacerlo:
Instala Angular Material: Primero, asegúrate de tener Angular Material integrado en tu proyecto, esto te proporcionará los componentes de UI necesarios.
Crea el select en el HTML: Reemplaza el input de texto en tu formulario con un mat-select. Este código es un ejemplo de cómo estructurar el select:
<mat-form-field appearance="fill"> <mat-label>Categoría</mat-label> <mat-select [(value)]="selectedCategoryId" [formControl]="formControls.categoryId"> <mat-option *ngFor="let category of categories" [value]="category.id"> {{ category.name }} </mat-option> </mat-select> </mat-form-field>
Configura el componente: Debes definir en el componente la lógica para obtener las categorías desde el API y almacenar las opciones en un array:
import { Component, OnInit } from '@angular/core'; import { CategoryService } from 'src/app/services/category.service'; // Asegúrate de tener el servicio apropiado export class ProductFormComponent implements OnInit { categories: Category[] = []; selectedCategoryId: string; constructor(private categoryService: CategoryService) {} ngOnInit(): void { this.getCategories(); } getCategories(): void { this.categoryService.getAllCategories().subscribe(categories => { this.categories = categories; }); } }
¿Cómo asegurar que el select refleja datos dinámicos?
La clave para que el select sea realmente dinámico es conectar y sincronizar los datos entre la API y el navegador del usuario de manera eficiente. Aquí te indico cómo lograrlo:
Uso de servicios en Angular: El servicio de categorías debe ser capaz de hacer llamadas HTTP y obtener datos del API.
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Category } from 'src/app/models/category.model'; @Injectable({ providedIn: 'root' }) export class CategoryService { private apiURL = 'api/categories'; // URL del API constructor(private http: HttpClient) {} getAllCategories(): Observable<Category[]> { return this.http.get<Category[]>(this.apiURL); } }
Sincronización con la interfaz: Asegúrate de que al inicializar el componente, los datos obtenidos del API se rendereen en la interfaz gráfica, permitiendo al usuario elegir solo categorías válidas.
¿Por qué es importante inicializar un array vacío?
Cuando trabajamos con arrays es buena práctica inicializarlos vacíos. Esto previene errores y asegura que nuestro *ngFor funcione correctamente en Angular. Aquí está el porqué:
categories: Category[] = [];
¿Cómo manejar la edición de productos con un formulario dinámico?
Al editar un producto, queremos que el formulario muestre la selección actual y lo actualice sin pérdida de datos. Aquí tienes los pasos para lograrlo:
Método patchValue de Angular: Este método permite llenar el formulario con datos preexistentes al cargar un producto específico.
Emparejamiento de IDs: Al utilizar patchValue, asegúrate de que los IDs de las categorías actuales coincidan para mostrar el valor preseleccionado en el select.
Implementar estas mejoras no solo aumenta la usabilidad de la aplicación, sino que también garantiza que solo categorías válidas sean seleccionadas y enviadas al backend. Esto siempre debe complementarse con una adecuada validación en el backend.
Una vez que domines la implementación con select, te reto a avanzar aún más, probando con otros tipos de input dinámicos como radio buttons. Aunque no es la práctica más convencional, te servirá como ejercicio para explorar nuevas capacidades del framework. ¡Sigue explorando y perfeccionando tus habilidades!
Horacio Castillejo
:)
Nicolas Molina
Profesor😀
Luis Gomero
😀
Para que funcione con la nueva API tuve que modificar el ngOnInit un poco, siendo honesto no me gusta del todo creo que se podria hacer mejor utilizando un combineLatest o un fokjoin para hacer las peticiones juntas, pero por el momento funciona:
ngOnInit() { this.getCategories() this.activatedRoute.params.subscribe((params: Params) => { this.id = params.id; this.productsService.getProduct(this.id) .subscribe(product => { this.form.patchValue(product); this.categoryIdField.setValue(product?.category.id) }); }); }
Y tambien agregar Category al modelo de products
import { Category } from "./category.model"; export interface Product { id: string; name: string; price: number; description: string; images: string[]; category?: Category }
JOHN WILAR SALAS BAUTISTA
Me parece que primero se debería cargar el listado de categorías y luego hacer el form.pachValue, por que si al cargar categorías tarda un poco, a la hora de hacer el patch no va encontrar la categoría y no lo seleccionara, ocasionando que siempre aparezca el primer item seleccionado.
Hugo Bustamante
Buenas tardes, no entiendo que papel tiene "[value]="category._id" en el select del componente editar, ayuda pls
Diego Fernando Caviedes Camaho
es el id de la categoria para enviar al backend
Fernando Garcia
en caso de no usar angular material, como puedo hacer para que salga "Seleccione un campo la siguiente lista" en el primer option asi como placeholder o que quede en selected el primero y al darle click despliegue la lista del ngFor
David Higuera
Podrías utilizar otro option con el valor default y el atributo selected
<option selected value="volvo">Select a option Please</option>
Diego Fernando Caviedes Camaho
<mat-select [(ngModel)]="selectedCategory" placeholder="Select a Category" formControlName="category_id" (change)="eventSelection($event)"> <mat-option *ngFor="let category of categories" [value]="category._id">{{ category.name }}</mat-option> </mat-select>
Manuel Alvarez
Me gusta mucho utilizar los select con Observables y asycn pipes, aunque a veces debo de utilizarlo de la forma normal por temas de procesos. muy buena clase Nico.