ufk
ufk

Reputation: 32104

map and filter on observable return empty result

I write an angular 12 application with rxjs that has a products categories list as a service stored in an observable, i am trying to create an observable that will return that categories that has an empty parent_category_id, the problem is that this observable returns an empty list.

this is my product category service:

import { Injectable } from '@angular/core';
import {ProductCategory} from '../types/product';
import {Observable, Subject} from 'rxjs';
import {map} from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ProductCategoriesService {

  private productCategories = new Subject<ProductCategory[]>();


  setProductCategories(pc: ProductCategory[]) {
    this.productCategories.next(pc);
  }

  get productCategories$(): Observable<ProductCategory[]> {
    return this.productCategories;
  }

  getRootProductCategories$(): Observable<ProductCategory[]> {
    return this.productCategories$.pipe(map((pc: ProductCategory[]) => pc.filter(p => p.parent_category_id === null)));
  }

}

in the component that displays the categories I created the following function:

 get getRootProductCategories$(): Observable<ProductCategory[]> {
    return this.pcService.getRootProductCategories$();
  }

and in it's view I have

<div id="product-categories">
  <app-product-category-card *ngFor="let rootProductCategories of getRootProductCategories$ | async"
               [url]="['/','products','X']" [title]="rootProductCategories.title"
                             img="XX">
  </app-product-category-card>

</div>

and i get no results.

now the problem is not with the filter rule, if i just type true in the filter rule it returns empty list.

if I change the function in the service to the following:

  getRootProductCategories$(): Observable<ProductCategory[]> {
    //return this.productCategories$.pipe(map((pc: ProductCategory[]) => pc.filter(p => p.parent_category_id === null)));
    return this.productCategories$.pipe();
  }

then I do get the full list of the categories, so I'm doing something wrong here I just don't know what.

any ideas ?

#updates

when I added tap() without json.stringify it returned something like this [ [Object] [Object]..., when I included json.stringify() it returns the proper object.

this is the code:

  getRootProductCategories$(): Observable<ProductCategory[]> {
    return this.productCategories$.pipe(tap(val => {
      console.log("Tap " + JSON.stringify(val));
    }),map((pc: ProductCategory[]) => pc.filter(p => p.parent_category_id === null)));
  }

this is the returned string:

Tap [{"id":1,"title":"מוצרי חשמל","description":"אלקטרוניקה","parent_category_id":null,"__typename":"ProductCategories"},{"id":2,"title":"לבית ולגן","description":"צינורות השקייה","parent_category_id":null,"__typename":"ProductCategories"},{"id":4,"title":"אביזרי רכב","description":null,"parent_category_id":null,"__typename":"ProductCategories"},{"id":5,"title":"קישוטי חיצוני","description":null,"parent_category_id":4,"__typename":"ProductCategories"},{"id":6,"title":"קישוט פנימי","description":null,"parent_category_id":4,"__typename":"ProductCategories"},{"id":3,"title":"4x4","description":null,"parent_category_id":5,"__typename":"ProductCategories"}]

Upvotes: 0

Views: 693

Answers (1)

chaimm
chaimm

Reputation: 400

not sure about your observable and when you expect it to emit, but a possiblility is because you are using a Subject that only will emit when you do a .next. can you try switching it to a BehaviorSubject, that will emit whenever something subscribes to it. (although I don't know why adding a .pipe() would change that)

Upvotes: 1

Related Questions