类型'OperatorFunction <response,recipe [] =“”>'上不存在属性'subscribe'

时间:2018-05-17 18:18:45

标签: angular rxjs

我正在尝试从firebase获取数据,但面临错误

  

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

任何想法?什么在这里失踪?

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

 }

3 个答案:

答案 0 :(得分:18)

让我着迷的是,许多功能都有一个静态版本和可移植版本。

例如,combineLatest(a$, b$).subscribe()会给您一个关于OperatorFunction<T,R>的类似错误(如果从rxjs / operators导入,则{T和R会根据您的观测值而变化)从rxjs导入它没有问题。

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

答案 1 :(得分:4)

您正在使用subscribe方法调用HTTP呼叫上的getRecipessubscribe的返回值属于Subscription,而非Observable。因此,您无法在storeRecipes方法中使用该值,因为无法观察到Subscription;只有Observable可以。

此外,您的getRecipes逻辑很糟糕。您在map中进行HTTP调用后使用getRecipes,但之前有分号。你有没有执行这段代码?它不是有效的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);
            })
        );
}

并确保从map导入taprxjs/operators

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

答案 2 :(得分:1)

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

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

您将运营商map传递到.pipe。您还可以在观察者身上调用.subscribe