exercises

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

products-list.component.ts (2370B)


      1 import { Component, effect, inject, input, signal } from '@angular/core';
      2 import { CommonModule } from '@angular/common';
      3 import { ProductService } from './products.service';
      4 import { Router } from '@angular/router';
      5 import { PaginateComponent } from './paginate.component';
      6 import { ProductComponent } from './product.component';
      7 
      8 @Component({
      9   selector: 'div.products-list',
     10   templateUrl: './products-list.component.html',
     11   styleUrls: ['./products-list.component.scss'],
     12   standalone: true,
     13   imports: [CommonModule, PaginateComponent, ProductComponent],
     14 })
     15 export class ProductsListComponent {
     16   private productService = inject(ProductService);
     17   private router = inject(Router);
     18 
     19   // Input signals automatically bound from query parameters
     20   readonly page = input<number, string | number>(1, {
     21     transform: (value: string | number) => {
     22       const num = typeof value === 'string' ? parseInt(value, 10) : value;
     23       return isNaN(num) ? 1 : Math.max(1, num);
     24     }
     25   });
     26   
     27   readonly pageSize = input<number, string | number>(10, {
     28     transform: (value: string | number) => {
     29       const num = typeof value === 'string' ? parseInt(value, 10) : value;
     30       return isNaN(num) || ![10, 20, 50, 100].includes(num) ? 10 : num;
     31     }
     32   });
     33 
     34   // State signals
     35   readonly products = signal<ProductCard[]>([]);
     36   readonly loading = signal<boolean>(false);
     37   readonly error = signal<string | null>(null);
     38   readonly totalPages = signal<number>(0);
     39   readonly total = signal<number>(0);
     40 
     41   constructor() {
     42     // Effect to load products when page or pageSize changes
     43     effect(() => {
     44       const currentPage = this.page();
     45       const currentPageSize = this.pageSize();
     46       this.loadProducts(currentPage, currentPageSize);
     47     });
     48   }
     49 
     50   private loadProducts(page: number, pageSize: number): void {
     51     this.loading.set(true);
     52     this.error.set(null);
     53 
     54     this.productService.getProducts(page, pageSize).subscribe({
     55       next: (response) => {
     56         this.products.set(response.products);
     57         this.totalPages.set(response.total_pages);
     58         this.total.set(response.total);
     59         this.loading.set(false);
     60       },
     61       error: (err) => {
     62         console.error('Failed to load products:', err);
     63         this.error.set('Failed to load products. Please try again.');
     64         this.products.set([]);
     65         this.loading.set(false);
     66       },
     67     });
     68   }
     69 }