【问题标题】:map and filter on observable return empty result映射和过滤可观察的返回空结果
【发布时间】:2021-10-07 22:03:42
【问题描述】:

我用 rxjs 编写了一个 Angular 12 应用程序,它有一个产品类别列表作为服务存储在一个 observable 中,我正在尝试创建一个 observable,它将返回具有空 parent_category_id 的类别,问题是这个observable 返回一个空列表。

这是我的产品分类服务:

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)));
  }

}

在显示类别的组件中,我创建了以下函数:

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

在它看来我有

<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>

我没有得到任何结果。

现在问题不在于过滤规则,如果我在过滤规则中输入true,它会返回空列表。

如果我将服务中的功能更改为以下内容:

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

然后我确实得到了完整的类别列表,所以我在这里做错了,我只是不知道是什么。

有什么想法吗?

#更新

当我添加不带 json.stringify 的 tap() 时,它返回类似 [ [Object] [Object]... 的内容,当我包含 json.stringify() 时,它返回正确的对象。

这是代码:

  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)));
  }

这是返回的字符串:

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"}]

【问题讨论】:

  • 您可以在map 方法之前放置一个tap 来记录您的数据并将其附加到帖子中吗?也许parent_category_id 不是null 因为你的后端序列化器把它变成了一个字符串或类似的东西。
  • filter() 将保留所有与谓词匹配的记录。在这种情况下,如果没有父类别为 NULL 的元素,则列表将为空
  • @Fussel 感谢您的输入,但正如我所说,如果在过滤器中我只返回 true,它仍然返回一个空列表。我将添加水龙头以查看发生了什么,但过滤规则不是这里的问题
  • 可能是你在这里缺少括号getRootProductCategories$ | async 吗?
  • @chaimm - 没有。它没有改变任何东西。

标签: angular rxjs observable


【解决方案1】:

不确定您的 observable 以及您希望它何时发射,但有可能是因为您使用的是 Subject,只有在您执行 .next 时才会发射。您可以尝试将其切换为BehaviorSubject,只要有人订阅它就会发出。 (虽然我不知道为什么添加 .pipe() 会改变这一点)

【讨论】:

  • 除了将变量类型更改为 BehaviorSubject 之外,我没有更改任何内容并且它起作用了。非常感谢
猜你喜欢
  • 2019-03-29
  • 1970-01-01
  • 2017-07-01
  • 2021-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
相关资源
最近更新 更多