“Observable<HttpEvent<>>”类型无法赋值给“Observable<>”类型。

8
我有这段代码片段:
SubmitTransaction(transNumber: string, transactionRequest: ITransactionRequestObj): Observable<TransactionResponse> {
    this.body =  JSON.stringify(transactionRequest);
    this.headers = new HttpHeaders().set('Content-Type', 'application/json');
    this.headers.append('Accept', 'application/json');
    this.options = new RequestOptions({headers: this.headers});
    return this.http.post<TransactionResponse>(this.baseUrl + '/transactions/' + transNumber + '/new',  this.body, this.options)
   .pipe(catchError((e) => this.errorHandler(e)));
  }

我只是将我的项目从Angular 5升级到Angular 6,并将.catch((e) => this.errorHandler(e));更改为.pipe(catchError((e) => this.errorHandler(e)));。然而,对于这个特定的方法,我得到了以下TypeScript错误。

错误:

[ts]
Type 'Observable<HttpEvent<TransactionResponse>>' is not assignable to type 'Observable<TransactionResponse>'.
  Type 'HttpEvent<TransactionResponse>' is not assignable to type 'TransactionResponse'.
    Type 'HttpSentEvent' is not assignable to type 'TransactionResponse'.
      Property '_transactionNumber' is missing in type 'HttpSentEvent'.

我不确定在这种情况下应该做什么。上面的代码片段在Angular 5中可以正常工作。我需要怎么做才能将其修复为适用于Angular 6?

编辑:

errorHandler(error: HttpErrorResponse) {
      return throwError(error.message || 'Server Error');
  }

我注意到如果我不使用HttpHeaders,它就能正常工作:
SubmitTransaction(transNumber: string, transactionRequest: ITransactionRequestObj): Observable<TransactionResponse> {
    this.body =  JSON.stringify(transactionRequest);
    this.headers = new HttpHeaders().set('Content-Type', 'application/json');
    this.headers.append('Accept', 'application/json');
    this.options = new RequestOptions({headers: this.headers});
    return this.http.post<TransactionResponse>(this.baseUrl + '/transactions/' + transNumber + '/new',  transactionRequest)
    .pipe(catchError((e) => this.errorHandler(e)));
  }

然而,在这种情况下,我可能需要使用HttpHeaders...有什么解决方法吗?

请发布您的错误处理程序代码。 - firegloves
@firegloves编辑了帖子。 - Euridice01
1
我认为HttpHeaders是不可变的,你应该将一些设置方法链接在一起,而不是追加。 - firegloves
使用Angular 6 / RxJs 6,请求体上不需要使用JSON.stringify()。除此之外,头部是不可变的,所以每次调用append都会返回一个新的headers对象实例。在函数调用中创建的大多数实例并不是真正必要的。你这样做有特别的原因吗?你是想为以后的使用缓存这些变量吗? - alexc
3个回答

1

HttpHeaders是一个不可变的数据结构。

append方法返回HttpHeaders的新实例,而不是修改现有实例,这意味着您需要在代码中进行微小的更改。

// old
this.headers.append('Accept', 'application/json')

// new
this.headers = this.headers.append('Accept', 'application/json')

更好的做法是一次性完成所有操作:

this.headers = new HttpHeaders()
  .set('Content-Type', 'application/json')
  .set('Accept', 'application/json')

谢谢。然而,我仍然遇到相同的错误。这个怎么样:this.options = new RequestOptions({headers: this.headers});?这正确吗?它抱怨在post中添加了this.options。 - Euridice01

0

你可以像这样传递选项:

headers: HttpHeaders = new HttpHeaders({
        'Content-Type': 'application/json',
    })

this.http.post<TransactionResponse>(this.baseUrl + '/transactions/' + transNumber + '/new',  this.body, {headers: this.headers})
       .pipe(catchError((e) => this.errorHandler(e)));

(或者)

你可以进行类型转换。this.http.post 返回的是 Observable<HttpEvent>,不能直接将其转换为 Observable。

this.http.post<TransactionResponse>(this.baseUrl + '/transactions/' + transNumber + '/new',  this.body, this.options)
   .pipe(catchError((e) => this.errorHandler(e))) as unknown as Observable<TransactionResponse>;

0
在 Angular 6 上运行此代码片段,RxJS 6 将不会出现上述错误而发出请求。它应该会为您提供与上面代码完全相同的结果:

SubmitTransaction(transNumber: string, transactionRequest: TransactionRequest): Observable<TransactionResponse> {
    return this.http
      .post<TransactionResponse>(`/myurl/transactions/${transNumber}/new`, transactionRequest, { headers: new HttpHeaders()
          .set('Accept', 'application/json') })
      .pipe(
        catchError(error => throwError(error.message || 'Server Error'))
      );
  }

我简化了代码,不再创建RequestOptions实例,而是将此过程留给HttpClient的post预处理流程,该流程会根据提供的哈希值为您创建实例。

我还从您的方法调用中删除了对body、headers和options的缓存。可以使用在post调用中声明的选项哈希中提取的变量将它们添加回去,但是,除非您想要缓存这些变量,否则没有必要这样做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接