【问题标题】:Property 'subscribe' does not exist on type 'OperatorFunction<Response, Recipe[]>''OperatorFunction<Response, Recipe[]>' 类型上不存在属性 'subscribe'
【发布时间】:2022-04-25 14:37:49
【问题描述】:

我正在尝试从firebase 获取数据,但遇到错误

“类型'OperatorFunction'上不存在属性'subscribe'”

有什么想法吗?这里缺少什么?

import { Injectable } from '@angular/core';
import {HttpClient, HttpResponse} from '@angular/common/http';
import {Response} from '@angular/http';
import {RecipeService} from '../recipes/recipe.service';
import {Recipe} from '../recipes/recipe.model';
import {map} from 'rxjs/operators';


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

 constructor(private httpClient: HttpClient,
          private recipeService: RecipeService) {}

 storeRecipes() {
    return this.httpClient.put('https://ng-recipe-10b53.firebaseio.com/recipes.json',
      this.recipeService.getRecipes());
 }

  getRecipes() {
this.httpClient.get('https://ng-recipe-book.firebaseio.com/recipes.json');
  map(
    (response: Response) => {
      const recipes: Recipe[] = response.json();
      for (const recipe of recipes) {
        if (!recipe['ingredients']) {
          recipe['ingredients'] = [];
        }
      }
      return recipes;
    }
  )
  .subscribe(
    (recipes: Recipe[]) => {
      this.recipeService.setRecipes(recipes);
    }
  );
 }

 }

【问题讨论】:

  • 应该没有“;”在您的获取请求结束时。地图应该是链式的。

标签: angular rxjs


【解决方案1】:

让我印象深刻的一件事是,有许多功能的静态和可管道版本。

例如,combineLatest(a$, b$).subscribe() 会给你一个关于 OperatorFunction&lt;T,R&gt; 的类似错误(T 和 R 会根据你的 observables 而有所不同)如果你从 rxjs/operators 导入它! 从 rxjs 导入它没问题。

如果您正在玩一些东西,您的 IDE 很可能会从 rxjs/operators 自动导入,并且在您尝试在管道外使用它时不会更改它。

【讨论】:

  • 这解决了我的问题。但是如果我们从 rxjs/operators 导入有什么问题呢?
  • 它本身没什么问题;这通常是首选的方法。问题是导出了两个不同的函数(例如combineLatest)。来自 rxjs/operators 的函数返回 OperatorFunction&lt;T,R&gt;(因此出现错误),而来自 rxjs 的函数返回 Observable&lt;R&gt;。看起来他们确实正在弃用非首选方式。例如,来自运营商的combineLatest 具有/** @deprecated Deprecated in favor of static combineLatest. */
  • 这只是糟糕的设计...有两个同名的函数-.-
【解决方案2】:

您在getRecipes 方法中的HTTP 调用中调用subscribesubscribe 的返回值是 Subscription 类型,而不是 Observable。因此,您不能在 storeRecipes 方法中使用该值,因为无法观察到 Subscription;只有Observable 可以。

此外,您的 getRecipes 逻辑很糟糕。在getRecipes 中的HTTP 调用之后使用map,但是它前面有一个分号。你甚至执行过这段代码吗?它不是有效的 TypeScript/Angular/RxJS,不会编译。

您可以正确链接您的运算符(使用旧的 RxJS 语法),或者使用pipeable operators,如下面的示例(新的 RxJS 语法)。

将您的 getRecipes 函数更改为此,它应该可以工作:

getRecipes() {
    this.httpClient
        .get('https://ng-recipe-book.firebaseio.com/recipes.json')
        .pipe(
            map((response: Response) => {
                const recipes: Recipe[] = response.json();
                for (const recipe of recipes) {
                    if (!recipe['ingredients']) {
                        recipe['ingredients'] = [];
                    }
                }
                return recipes;
            }),
            tap((recipes: Recipe[]) => {
                this.recipeService.setRecipes(recipes);
            })
        );
}

并确保从rxjs/operators 导入maptap

import { map, tap } from 'rxjs/operators';

【讨论】:

  • 没问题。随意接受您认为最能解决您的问题的答案。
【解决方案3】:

你想在 RxJS 中使用pipeable operators。这些是您传递给 Observables 的 .pipe 方法以对 Observable 发出的元素进行操作的函数。你也可以在 Observables 上调用 .subscribe。运算符没有.subscribe 方法。

this.httpClient.get(...).pipe(
  map(...)
).subscribe(...);

您将运算符map 传递给.pipe。您还可以在 observable 本身上调用 .subscribe

【讨论】:

    【解决方案4】:

    我通过在最后添加一个括号来解决我的问题,因为我忘记了它XD

    of(1,2,3).pipe(scan((acc, curr)=> acc + curr, 0).subscribe(console.log)
    

    给出这个错误。

    of(1,2,3).pipe(scan((acc, curr)=> acc + curr, 0) ).subscribe(console.log)
    

    不再给出这个错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 2016-09-09
      相关资源
      最近更新 更多