diff --git a/src/app/pages/category/._subcategories.component.html b/src/app/pages/category/._subcategories.component.html new file mode 100644 index 0000000..707ba9b Binary files /dev/null and b/src/app/pages/category/._subcategories.component.html differ diff --git a/src/app/pages/category/category.component.ts b/src/app/pages/category/category.component.ts index e7c13dd..3b7701c 100644 --- a/src/app/pages/category/category.component.ts +++ b/src/app/pages/category/category.component.ts @@ -40,9 +40,10 @@ export class CategoryComponent implements OnInit, OnDestroy { ngOnInit(): void { this.routeSubscription = this.route.params.subscribe(params => { - const id = Number.parseInt(params['id'], 10); + const rawId = params['id']; + const id = Number(rawId); - if (!Number.isFinite(id) || id <= 0) { + if (!Number.isInteger(id) || id <= 0 || String(id) !== String(rawId)) { this.error.set('Invalid category ID'); this.items.set([]); this.hasMore.set(false); diff --git a/src/app/pages/category/subcategories.component.html b/src/app/pages/category/subcategories.component.html index 28c977a..0800d93 100644 --- a/src/app/pages/category/subcategories.component.html +++ b/src/app/pages/category/subcategories.component.html @@ -22,7 +22,11 @@ @if (nestedSubcategories().length > 0) {
@for (sub of nestedSubcategories(); track trackBySubId($index, sub)) { - + @if (getSubcategoryRouteId(sub) !== null) { + + } else { +
+ }
@if (sub.img) { @@ -36,7 +40,11 @@ {{ sub.itemCount }} }
-
+ @if (getSubcategoryRouteId(sub) !== null) { + + } else { +
+ } }
} diff --git a/src/app/pages/category/subcategories.component.ts b/src/app/pages/category/subcategories.component.ts index 805963f..793341c 100644 --- a/src/app/pages/category/subcategories.component.ts +++ b/src/app/pages/category/subcategories.component.ts @@ -41,9 +41,10 @@ export class SubcategoriesComponent implements OnInit, OnDestroy { ngOnInit(): void { this.routeSubscription = this.route.params.subscribe(params => { - const id = Number.parseInt(params['id'], 10); + const rawId = params['id']; + const id = Number(rawId); - if (!Number.isFinite(id) || id <= 0) { + if (!Number.isInteger(id) || id <= 0 || String(id) !== String(rawId)) { this.error.set('Invalid category ID'); this.categories.set([]); this.subcategories.set([]); @@ -140,6 +141,15 @@ export class SubcategoriesComponent implements OnInit, OnDestroy { return sub.id; } + getSubcategoryRouteId(sub: Subcategory): number | null { + if (!sub?.id) return null; + const id = Number(sub.id); + if (!Number.isInteger(id) || id <= 0 || String(id) !== String(sub.id)) { + return null; + } + return id; + } + readonly getDiscountedPrice = getDiscountedPrice; readonly getMainImage = getMainImage; readonly trackByItemId = trackByItemId; diff --git a/src/app/services/._api.service.ts b/src/app/services/._api.service.ts new file mode 100644 index 0000000..707ba9b Binary files /dev/null and b/src/app/services/._api.service.ts differ diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index ef45d1b..1cde4a2 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { HttpClient, HttpParams } from '@angular/common/http'; -import { Observable, timer } from 'rxjs'; +import { Observable, timer, throwError } from 'rxjs'; import { map, retry } from 'rxjs/operators'; import { Category, Item, Subcategory } from '../models'; import { environment } from '../../environments/environment'; @@ -267,6 +267,10 @@ export class ApiService { } getCategoryItems(categoryID: number, count: number = 50, skip: number = 0): Observable { + if (!Number.isInteger(categoryID) || categoryID <= 0) { + return throwError(() => new Error('Invalid category ID')); + } + const params = new HttpParams() .set('count', count.toString()) .set('skip', skip.toString());