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); }); }; }
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
.
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
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.