Reputation: 191
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!
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
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
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