在Angular 5中订阅SwitchMap

时间:2018-10-20 15:45:09

标签: angular typescript firebase angular5

我正在尝试显示一个包含所有产品的页面和一个包含类别的部分,但是只有类别正在呈现。

我在页面上没有看到产品。

控制台显示错误:

main.653279d3d097093b55e7.js:1 ERROR Error: InvalidPipeArgument: '[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]' for pipe 't'

我的代码:

import { Component, OnInit } from '@angular/core';
import { ProductService } from '../product.service';
import { Observable, Subscription } from 'rxjs';
import { AngularFireList } from 'angularfire2/database';
import { map, switchMap, filter } from 'rxjs/operators';
import { CategoryService } from '../category.service';
import { ActivatedRoute } from '@angular/router';
import { Product } from '../models/product';

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
  products: any = {};
  productsRef: AngularFireList<any>;
  filteredProducts;
  categories: Observable<any>;
  categoriesRef: AngularFireList<any>;
  category;

  constructor(route: ActivatedRoute, private productService: ProductService, private categoryService: CategoryService) {

    this.productsRef = productService.getAll();

    this.products = this.productsRef.snapshotChanges().pipe(
      map(changes =>
        changes.map(c => ({key: c.payload.key, ...c.payload.val() }))
      )).switchMap (products => {
        this.products = products;
        return route.queryParamMap;
      }).subscribe (params => {
        this.category = params.get('category');
        this.filteredProducts = (this.category) ?
          this.products.filter(p => p.category === this.category) : this.products;
      });

    this.categoriesRef = this.categoryService.getAll();

    this.categories = this.categoriesRef.snapshotChanges().pipe(
        map(changes =>
          changes.map(c => ({key: c.payload.key, ...c.payload.val() }))
        )
      );

有什么建议解决此问题吗?

2 个答案:

答案 0 :(得分:0)

您应该使用pipe()

 this.products = this.productsRef.snapshotChanges().pipe(
      map(changes =>
        changes.map(c => ({key: c.payload.key, ...c.payload.val() }))
      ),
switchMap (products => {
        this.products = products;
        return route.queryParamMap;
      })
).subscribe (params => {
        this.category = params.get('category');
        this.filteredProducts = (this.category) ?
          this.products.filter(p => p.category === this.category) : this.products;
      });

答案 1 :(得分:0)

switchMap签名期望此函数将返回Observable<any>

public switchMap(project: function(value: T, ?index: number): ObservableInput, resultSelector: function(outerValue: T, innerValue: I, outerIndex: number, innerIndex: number): any): Observable

当您返回的不是route.queryParamMap类型的ObservableInput时。尝试替换此行:

return route.queryParamMap;

与此:

return Observable.from(route.queryParamMap);

编辑

由于我的错误导致我的第一个答案无效,因此我尝试将您的strem重新写成一个不使用pipe并在其开头使用switchMap的字符串,以防止重新查询不完整的词条。

this.products = this.productsRef.snapshotChanges()
.switchMap((products: AngularFireAction<DatabaseSnapshot>[]) => {
    return Observable.of(products); // Just re-emit things to guard re-query interruption
})
.map((snap: AngularFireAction<DatabaseSnapshot>[]) => { /* Do data manipulation */
  let mappedProducts = snap.map((s: AngularFireAction<DatabaseSnapshot>) => {
    return {key: s.payload.key, ...c.payload.val() }
  })
  return mappedProducts;
})
.do((mappedProducts: any) => { /* Side effects */
  this.products = mappedProducts;
})
.concatMap(mappedProducts => {
  return route.queryParamMap;
})
.subscribe (params => {
  this.category = params.get('category');
  this.filteredProducts = (this.category) ?
    this.products.filter(p => p.category === this.category) : this.products;
});