【问题标题】:"rxjs" observable.throw is not a function - Angular4“rxjs” observable.throw 不是函数 - Angular4
【发布时间】:2018-01-09 21:59:13
【问题描述】:

我一直在学习 Angular 4,一切都很顺利,直到我尝试在服务中实现 catch 处理。我正在尝试使用“rxjs”捕捉并抛出,​​但我的控制台中有一个未定义的函数错误。

import { Injectable } from '@angular/core';
import { Http } from "@angular/http";
import { Observable } from 'rxjs/observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import { AppError } from "../app/common/app.error";
import { NotFoundError } from "../app/common/not-found-error";
import { BadInput } from "../app/common/bad-input";

@Injectable()
export class PostService {
  private url = "https://jsonplaceholder.typicode.com/posts";

  constructor(private http: Http) { }

 deletepost(post){
      // return this.http.delete(this.url + '/' + post.id)
      // Hard-coded id to test 404
      return this.http.delete(this.url + '/' + 93498)
        .catch((error: Response) => {
          console.log('error within catch is ' + Response)
          if(error.status === 404)
            return Observable.throw(new NotFoundError(error));

          return Observable.throw(new AppError(error));
        });
    }
}

这是错误信息:

TypeError: __WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw is not a function. 
(In '__WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw(new 
__WEBPACK_IMPORTED_MODULE_6__app_common_not_found_error__["a" /* NotFoundError 
*/](error))', 
'__WEBPACK_IMPORTED_MODULE_2_rxjs_observable__["Observable"].throw' is 
undefined) — post.service.ts:42

我的浏览器中也有这个警告:

./~/rxjs/Observable.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
* /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/rxjs/Observable.js
    Used by 14 module(s), i. e.
    /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/@angular/core/@angular/core.es5.js
* /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/rxjs/observable.js
    Used by 1 module(s), i. e.
    /Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/node_modules/@ngtools/webpack/src/index.js!/Users/nickgowdy/Desktop/Angular2/angular4 source code/hello-world/src/services/post.service.ts

【问题讨论】:

  • 尝试使用大写“O”导入import { Observable } from 'rxjs/Observable';,而不是使用小写“o”导入import { Observable } from 'rxjs/observable';,看看是否有任何不同。
  • @AlexanderStaroselsky 哇,我不敢相信这就是原因。我没有注意到它是大写 O,因为它与所有其他导入依赖项的命名约定不匹配。您应该将此作为答案发布,以便我将其标记为正确。
  • 我也经历过同样的事情,错误并不总是很清楚。介意我将其作为答案,以便其他遇到此问题的人可以找到解决方案吗?
  • @AlexanderStaroselsky 是的,去吧。为这个问题创建一个答案,我会将其标记为正确。感谢您的帮助。

标签: angular rxjs observable throw


【解决方案1】:

错误There are multiple modules with names that only differ in casing. 表示错误的导入是针对您尝试使用Observable 的方式。

导入应使用大写“O”,例如:

import { Observable } from 'rxjs/Observable';

这将导入单独的 Observable 运算符,这些运算符可与创建的 Observable 上的 catchthrow 等运算符结合使用。

import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

要导入完整的 Observable 对象,您可以像这样导入它:

import { Observable } from 'rxjs/Rx'

更新:

对于较新版本的 RxJS (5.5+) 运算符,例如 map()filter() 可以用作 pipeable operatorspipe() 结合使用,而不是链接。它们被导入,例如:

import { filter, map, catchError } from 'rxjs/operators';

请记住,throw 等术语在 JavaScript 中是保留/关键字,因此 RxJS throw 运算符导入为:

import { _throw } from 'rxjs/observable/throw';

更新:

对于较新版本的 RxJS (6+),使用这个:

import { throwError } from 'rxjs';

并抛出这样的错误:

if (error.status === 404)
    return throwError( new NotFoundError(error) )

【讨论】:

  • 导入完整的 Observable - import { Observable } from 'rxjs/Rx' - 增加包的大小。来自文档:github.com/ReactiveX/rxjs 通过修补仅导入您需要的内容(这对于大小敏感的捆绑很有用): import { Observable } from 'rxjs/Observable';导入'rxjs/add/observable/of';导入'rxjs/add/operator/map';
  • 是的,import { Observable } from 'rxjs/Rx'; 在导入完整的Observable 对象时会显着增加捆绑包的大小。在大多数情况下,我认为它只是不需要,但我想将它作为一个选项提供,因为每个应用程序都不同,并且可能需要这种控制。
  • @AlexanderStaroselsky 祝福你帮了我很多忙,从“rxjs/Observable”导入 {Observable} 和从“rxjs 导入 {Observable}”有什么区别,因为我遇到了 Observable throw(error) 的问题仅当我最后删除 /Observable 时才有效
  • @valik 如果没有/Observable,听起来您可能会导入包含throw 等方法的完整Observable 对象。根据您的 RxJS 版本,我建议避免导入完整的 Observable 对象,而是使用 Pipeable Operators。 Angular 有文档演示如何使用 RxJS,包括使用 catchError 处理错误。导入完整的 Observable 对象会带来您可能根本不需要的东西。
  • Observable.throw() 不适用于 import { Observable } from 'rxjs/Observable'; 当通过 import { Observable } from 'rxjs/Rx'; 或简单地通过 import { Observable } from 'rxjs'; 导入完整的 Observable 对象时,throw() 等方法可用于 Observable。但是你可以import { Observable } from 'rxjs/Observable'; 然后import 'rxjs/add/observable/throw'; 它应该可以工作。检查此StackBlitz。我还建议您创建一个新问题来帮助解决您遇到的任何具体问题。
【解决方案2】:

我在angular 5 应用程序中遇到了同样的问题。我所做的是,添加一个新包。

import { throwError } from 'rxjs';
import { filter, map, catchError } from 'rxjs/operators';

从我的http 服务调用中,我返回了一个函数。

return this.http.request(request)
      .pipe(map((res: Response) => res.json()),
        catchError((res: Response) => this.onError(res)));

onError 函数中,我使用throwError(error) 返回错误。

onError(res: Response) {
    const statusCode = res.status;
    const body = res.json();
    const error = {
      statusCode: statusCode,
      error: body.error
    };
    return throwError(error);
  }

【讨论】:

  • 此解决方案适用于我的 Angular 6 应用程序 w/rxjs 6.0。我的 import 语句已经 import { Observable } from 'rxjs/Observable' ,虽然这样做我仍然得到 Observable.throw is not a function 错误。我尝试了 import 'rxjs/add/observable/throw' 但它给出了编译器错误。
  • 谢谢西比什!!
【解决方案3】:

在 RxJS 6 中,Observable.throw()throwError() 取代,其操作与其前身非常相似。 因此,您可以通过导入将Observable.throw(error) 替换为仅throwError(error)

import { throwError } from 'rxjs';

查看此链接以获取更多参考:https://www.metaltoad.com/blog/angular-6-upgrading-api-calls-rxjs-6

【讨论】:

  • 这救了我!这是新修复
【解决方案4】:

_throw 在较新版本的 RxJS 中已被丢弃
对于较新版本的 RxJS (6+),请使用:

 import { throwError } from 'rxjs'; 

并抛出这样的错误:

 if (error.status === 404)
    返回 throwError(新的 NotFoundError(错误))

【讨论】:

  • 这对我有用。 throwError 继承自 Observable,所以它是直接交换。
【解决方案5】:

在 Angular9 Observable 中:

  1. 如果数据到达且状态正常,则发送数据
  2. 如果数据的 STATUS 不正常,则抛出错误
myObsFunc(): Observable<any> { 
  return this.http.get<any>('/api/something') 
    .pipe(
      /* Catch a backend error and let the component know */
      catchError( err => {
        /* Rethrow error */
        return throwError( err );
      }),
      map( (res)=> {
        if( res.STATUS == "OK" ) {
          /* Send DATA to subscriber */
          return Object.values( res.DATA)
        } else {
           /* Inform subscriber that a functional error occured */
           throw ( "getOrphans: Status is not OK but "+ res.STATUS ) ;
        }   
      }),
    )   
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    相关资源
    最近更新 更多