I have been having issues in implementing a filter of item categories in an ecommerce being built using NodeJs and Angular

217 views Asked by At

In the following code snippets you the filter functions doesn't work. Component HTML:

<div class="products-page">
<div class="grid">
    <div class="col-3">
     <h4>Categories</h4>
     <div class="p-field-checkbox" *ngFor="let category of categories">
        <label for="{{category.id}}">{{category.name}}</label>
        <p-checkbox
        [(ngModel)]="category.checked"
        binary="true"
        [inputId]="category.id"
        (onChange)="categoryFilter()"
      ></p-checkbox>
      <label for="{{ category.id }}">{{ category.name }}</label>
    </div>
    </div>
    <div class="col-9">
        <div class="grid" *ngIf="products">
            <div class="col-4" *ngFor="let product of products">

                <eshop-frontend-product-item [product] ="product"></eshop-frontend-product-item>
            </div>
        </div>
    </div>
</div>

Component TS:

import { Component, OnInit } from '@angular/core';
import { ProductsService } from '../../services/products.service';
import { Product } from '../../models/product';
import { CategoriesService } from '../../services/categories.service';
import { Category } from '../../models/category';

@Component({
  selector: 'eshop-frontend-products-list',
  templateUrl: './products-list.component.html',
  styles: [
  ]
})
export class ProductsListComponent implements OnInit {
  isChecked = false
  products: Product[] = [];
  categories: Category[] = [];

  constructor(private prodService: ProductsService, private catService: CategoriesService) { }

  ngOnInit(): void {
    this._getProducts();
    this._getCategories();
  }

  private _getProducts(categoriesFilter?: string[]) {
    this.prodService.getProducts(categoriesFilter).subscribe((resProducts) => {
      this.products = resProducts;
    });
  }

  private _getCategories(){
    this.catService.getCategories().subscribe(resCats =>{
      this.categories = resCats;
    })
  }

  categoryFilter() {
    const selectedCategories: string | any = this.categories
      .filter((category) => category.checked)
      .map((category) => category.id);

    this._getProducts(selectedCategories);
  }


}

Products Service:

import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from '@env/environment';
import { Product } from '../models/product';

@Injectable({
  providedIn: 'root',
})
export class ProductsService {
  apiUrlProducts = environment.apiURL + 'products';

  constructor(private http: HttpClient) {}
  getProducts(categoriesFilter?: string[]): Observable<Product[]> {
    let params = new HttpParams();
    if (categoriesFilter) {
      params = params.append('categories', categoriesFilter.join(','));
    }
    return this.http.get<Product[]>(this.apiUrlProducts, { params: params });
  }



  createProduct(productData: FormData): Observable<Product> {
    return this.http.post<Product>(this.apiUrlProducts, productData);
  }

  getProduct(productId: string): Observable<Product> {
   return this.http.get<Product>(`${this.apiUrlProducts}/${productId}`);
 }

  updateProduct(productData: FormData, productid: string): Observable<Product> {
    return this.http.put<Product>(`${this.apiUrlProducts}/${productid}`, productData);
  }


deleteProduct(productId: string): Observable<any> {
  return this.http.delete<any>(`${this.apiUrlProducts}/${productId}`);
}

getProductsCount(): Observable<number> {
  return this.http
    .get<number>(`${this.apiUrlProducts}/get/count`)
    .pipe(map((objectValue: any) => objectValue.productCount));
}

getFeaturedProducts(): Observable<Product[]>{
  return this.http.get<Product[]>(`${this.apiUrlProducts}/get/featured/`);
}
}

Errors:

[(ngModel)]="category.checked" Property 'checked' does not exist on type 'Category';

[inputId]="category.id" Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'

In the backend i do not have the checked field, I was under the impression that it was not necessary to add it, I have also witnessed several example where this is not implemented and still works fine. I have been stuk for a long time and there seems to be nothing useful out there, can you please advise?

2

There are 2 answers

0
RomainG On
  1. [(ngModel)]="category.checked" Property 'checked' does not exist on type 'Category';

You can check in your interface in import { Category } from '../../models/category'; if there a property called checked. Otherwise, add the "checked" property to the category interface.

  1. [inputId]="category.id" Type 'string | undefined' is not assignable to type 'string'. Type 'undefined' is not assignable to type 'string'.

Again check your Category interface, maybe the property "id" has a type like that string | undefined. Remove the "| undefined" and it sould work.

1
pakorn suwanarat On

models/category.ts:

export class Category {
    id?: string;
    name?: string;
    icon?: string;
    color?: string;
    checked?: boolean;
}