moses
moses

Reputation: 191

Observable rxjs filter

In my project, I wanted to create some sort of "Recommended Products" in each product page, but having trouble with making my function filtering an observable.

I have tried using .pipe(filter()) in different ways, but to no use.

Basically the fucntion should filter products with the same type and id, and show them in the proper product page, but pretty much got stuck after subscribing all of my products(which is marked down below).

Much Appreciated!

enter image description here

import { Component, OnInit } from '@angular/core';
import { ProductService } from '../services/product.service';
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import  Product  from '../interfaces/product';
import { map, filter} from 'rxjs/operators';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-product',
  templateUrl: './product.component.html',
  styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
  recommandedProducts: Product[];
  allProducts:Product[];
  // allProducts:Observable< Product> = new Observable< Product>();
  product: Product;
  


  constructor(private productService: ProductService, private route: Router, private actRoute: ActivatedRoute) { }

  ngOnInit() {
    this.findRecommendedProducts(this.product)
  };

//From ProductService:
//   getProducts(){
//    return this.http.get(`${this.uri}`);
//    }
  findRecommendedProducts(currectProduct: Product){
    this.productService.getProducts().subscribe((data: Product[]) => {
      this.allProducts = data;
      console.log(this.allProducts)
      this.recommandedProducts = this.allProducts.filter(otherProduct => 
      otherProduct.type == currectProduct.type && otherProduct.id == currectProduct.id)
      console.log(this.recommandedProducts);
    });      
  };



}

Upvotes: 1

Views: 793

Answers (2)

nash11
nash11

Reputation: 8650

A filter in rxjs is not the same as an Array.filter. In rxjs, a filter is used to emit values that pass the provided condition. So if you use a filter, based on the condition, the observable will either emit your data or return nothing.

Instead, what you need is pipe(map) along with an Array.filter. Also, as @jzzfs pointed out, your error shows currentProduct could be undefined, so you can pass a default value in your findRecommendedProducts function.

Try the below code.

findRecommendedProducts(currectProduct: Product = {} as Product) {
    this.productService.getProducts()
    .pipe(
        map((products: Product[]) => products.filter(product => product.type == currectProduct.type && product.id == currectProduct.id))
    )
    .subscribe((data: Product[]) => {
        this.recommandedProducts = data;
    });      
};

Now your subscribed data should directly return the recommendedProducts.

Upvotes: 1

Joe - Check out my books
Joe - Check out my books

Reputation: 16925

Looks like the currectProduct passed onto findRecommendedProducts is undefined, since the logged this.allProducts do contain values.

With that being said, notice that when you define product: Product, you've only defined its type but you have not initialized it. The default value is therefore undefined -- if I remember correctly.

So change product: Product to product: Product = {};, for instance or pass a value to it within the constructor or within ngInit.

Upvotes: 0

Related Questions