creo estaría mejor si el profe escribe el código durante la clase, pasa que cuando copia y pega se mueve de archivos y por hacerlo rapido no explica claro lo que esta haciendo y es confuso
Manejo de rutas
Qué aprenderás sobre Angular Router y programación modular
Creando rutas
Creando el Home
Página de categorías
Evitando doble subscribe
RouterLink y RouterActive
Ruta 404
Detalle de cada producto
Parametros URL
Módulos
LazyLoading y CodeSplitting
Programación Modular
Vistas anidadas
Creando el CMS Module
Creando en Website Module
Creando un Shared Module
Precarga de módulos
Precarga de módulos
All Modules y Custom Strategy
QuickLink Strategy
Guardianes
Conoce a los Guardianes
Implementando redirects
Estado de login
Guard para Admin
CanDeactivate
Deployment
Netlify Deployment
Despedida
Despedida
Crea una cuenta o inicia sesión
¡Continúa aprendiendo sin ningún costo! Únete y comienza a potenciar tu carrera
No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial
Antes: $249
Paga en 4 cuotas sin intereses
Termina en:
Cuando construyes URLs en tu aplicación, éstas pueden poseer parámetros dinámicos, por lo general, IDs para identificar registros, para capturarlos y manipularlos posteriormente.
Veamos a continuación dos maneras de capturar estos parámetros, una síncrona y otra asíncrona.
El mejor lugar para capturar parámetros de URL, sean síncronos o no, es utilizando los hooks de ciclo de vida de Angular, más concretamente ngOnInit()
.
Comienza creando tus rutas que permitan ingresar parámetros dinámicos de la siguiente manera:
// app-routing.module.ts
const routes: Routes = [
{
path: 'catalogo',
component: CatalogoComponent
},
{
path: 'catalogo/:categoryId',
component: CatalogoComponent
},
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Observa que ambas rutas apuntan al mismo componente, eso está bien. La diferencia estará en que la segunda ruta posee :categoryId
y podrás capturar el parámetro utilizando ese mismo nombre.
En el componente correspondiente, inyecta el servicio ActivatedRoute y también importa Params para tipar tus datos y manipularlos más fácilmente. Ambos imports provenientes de @angular/router
.
// modules/website/components/catalogo/catalogo.components.ts
import { ActivatedRoute, Params, Router } from '@angular/router';
@Component({
selector: 'app-catalogo',
templateUrl: './catalogo.component.html',
styleUrls: ['./catalogo.component.scss']
})
export class CatalogoComponent {
constructor(private route: ActivatedRoute) { }
}
Es momento de capturar los parámetros en el ngOnInit()
. Para esto, basta con una línea de código como la siguiente:
// modules/website/components/catalogo/catalogo.components.ts
ngOnInit(): void {
const categoryId = this.route.snapshot.paramMap.get('categoryId');
console.log(categoryId);
}
Guardarás en la constante categoryId
el valor del parámetro que lleva el mismo nombre que definiste en el archivo app-routing.module.ts
. Luego podrás utilizarlos para realizar peticiones a un servidor o para lo que necesites.
Una URL puede cambiar y a veces es conveniente estar escuchando de forma activa los cambios en la misma.
Para que los Observables nos ayuden a estar atentos a estos cambios, Angular también nos permite suscribirnos a los cambios en los parámetros de URL de la siguiente manera.
// modules/website/components/catalogo/catalogo.components.ts
ngOnInit(): void {
this.route.paramMap
.subscribe((params: Params) => {
const categoryId = params.get('categoryId');
console.log(categoryId);
});
}
A través del nombre del parámetro definido en el archivo app-routing.module.ts
, capturas los datos para manipularlos posteriormente.
De esta manera, puedes pasar parámetros dinámicamente, de forma síncrona o asíncrona, dependiendo tu necesidad y construir tu aplicación.
Contribución creada por: Kevin Fiorentino.
Aportes 8
Preguntas 6
creo estaría mejor si el profe escribe el código durante la clase, pasa que cuando copia y pega se mueve de archivos y por hacerlo rapido no explica claro lo que esta haciendo y es confuso
Aquí tenemos la url de la documentación de la API
A mi me estaba saliendo error al obtener el id con:
params.get('id')
lo que hice fue obtenerlo de esta forma:
this.categoryId = params['id'];
Para que les funcione para el 2023 tienen que modificar el archivo environment.ts:
export const environment = {
production: false,
API_URL: 'https://api.escuelajs.co/api/v1',
};
quedaria asi para las categories:
return this.http.get<Product[]>(`${this.apiUrl}/categories/${categoryId}/products`, { params })
hay que hacer ciertas modificacioens en las demas rutas, pero se puede usar el swagger UI como guia
Estoy lista
Buenas a todos, yo me desvié un poco de la línea que mantenía el profe y creé una paginación al estilo de page up page down, entonces para ello, en estos momentos mi código es algo diferente, pero lo más asombroso es que funciona para products en el home y en categories os dejo un avance aquí y un enlace al repo.
// category.component.ts
onPageUp(){
if (this.limit * (this.page + 1) < this.MAX_PRODUCTS_IN_BD ) {
this.page += 1;
this.offset = this.limit * this.page;
this.productsService.getProductsByPage(this.limit, this.offset)
.subscribe(data => {
this.products = data;
});
}
}
// category.component.html
<app-products [products]="products" [page]="page" (pageUp)="onPageUp()" (pageDown)="onPageDown()"></app-products>
// products.componet.ts
@Input() products: Product[] = [];
@Input() page=0;
@Output() pageUp = new EventEmitter();
@Output() pageDown = new EventEmitter();
// ...
onPageUp(){
this.pageUp.emit();
}
onPageDown(){
this.pageDown.emit();
}
ver todo el código en este repo de github
Solucion del reto
loadMore(): void {
this.route.paramMap.subscribe((params) => {
this.categoryId = params.get('id');
if (this.categoryId) {
this.productsService
.getByCategory(this.categoryId, this.limit, this.offset)
.subscribe((data) => {
this.products = this.products.concat(
data.filter((product) => product.images.length > 0)
);
this.offset += this.limit;
});
}
});
}
Lo que hice en este caso es manejar un router a un home despues de que haga login, esto validado con Guards.
Y ya lo que hice fue manejar todas las peticiones desde el products, aunque no se si es buena practica siento que es mas ordenado la manera que lo hace el profe. Pero les comparto el codigo.
Esto sin nada de inputs ni nada de logica en el home.
products.ts component
constructor(
private storeServices: StoreService,
private productService: ProductsService,
private filesService: FilesService,
private activatedRoute: ActivatedRoute
) {
this.myShoppingCart = this.storeServices.getShopingCart()
}
ngOnInit(): void {
this.activatedRoute.params.subscribe(params => {
this.categoryId = params['id'];
if (this.categoryId) {
this.loadCategoryProducts(this.categoryId)
}
});
this.loadProducts()
}
loadCategoryProducts(categoryId: string) {
this.categoryId = categoryId;
this.products = [];
this.offset = 0;
this.loadProducts();
}
loadProducts() {
const request$ = this.categoryId ?
this.productService.getCategory(this.categoryId, this.limit, this.offset) :
this.productService.getAllProducts(this.limit, this.offset)
request$
.subscribe({
next: (data: Product[]) => {
this.products = this.products.concat(data);
this.offset += this.limit;
if (data.length === 0) {
this.offset = 0;
}
},
error: (error: string) => {
this.loadingProducts = false
Swal.fire({
title: 'Error!',
text: error,
icon: 'error',
confirmButtonText: 'Ok',
});
},
});
}
loadMoreProducts() {
this.offset += this.limit;
this.loadProducts();
}
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?