升级到Angular 6.0并将Rxjs升级到6.0后,我收到以下编译错误:
Property 'do' does not exist on type 'Observable'.
以下是代码:
import { Observable, of } from 'rxjs';
import 'rxjs/add/operator/do';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/catch';
import { IProduct } from './product';
@Injectable()
export class ProductService {
constructor(
private product: IProduct)
{
}
getProduct = () => {
return product.products
// error on next line
.do(data => console.log('All:' + JSON.stringify(data)))
.catch(this.handleError);
}
private handleError(err: HttpErrorResponse) {
console.log(err.message);
return Observable.throw(err.message);
}
}
有什么想法吗?
答案 0 :(得分:64)
问题不在于角度,而在于rxjs。 rxjs引入了rxjs版本6的重大更改。
要在不更改任何代码的情况下重新运行代码,请安装以下软件包:
npm install rxjs-compat@6 --save
然后您应该能够编译您的项目。 rxjs-compat
旨在成为临时解决方案,因此您需要更新代码库以使用新版本。
您需要更新的内容:
从
更新导入语句 import { Observable } from "rxjs/Observable";
到
import { Observable } from "rxjs";
从
更新您的运营商导入 import 'rxjs/add/operator/do'
以强>
import { do } from "rxjs/operators";
由于与JavaScript保留字的名称冲突,某些运算符也已重命名。他们是
do
=> tap
catch
=> catchError
switch
=> switchAll
finally
=> finalize
然后,您也无法使用pipe
运算符链接您的运算符,例如
// an operator chain
source
.map(x => x + x)
.mergeMap(n => of(n + 1, n + 2)
.filter(x => x % 1 == 0)
.scan((acc, x) => acc + x, 0)
)
.catch(err => of('error found'))
.subscribe(printResult);
// must be updated to a pipe flow
source.pipe(
map(x => x + x),
mergeMap(n => of(n + 1, n + 2).pipe(
filter(x => x % 1 == 0),
scan((acc, x) => acc + x, 0),
)),
catchError(err => of('error found')),
).subscribe(printResult);
答案 1 :(得分:11)
Rxjs 6引入了一些重大变化,“do”运算符已被“tap”运算符替换(来自“rxjs/internal/operators
”)。
您可以使用new运算符重构代码,或者仍然使用旧的'do'语法,通过添加rxjs-compat库以实现向后兼容性(npm install --save rxjs-compat
)。
请注意,在RxJs 6之前,您必须导入'do'运算符:
import 'rxjs/add/operator/do';
此处有更多详情:Angular HTTP GET with TypeScript error http.get(...).map is not a function in [null]
答案 2 :(得分:4)
我感谢Tjaart van der Walt关于如何解决Angular / rxjs7 ++中引入的“重大更改”的答复。但是在尝试将他的响应应用于我的Angular拦截器时,我仍然遇到一些问题:
这是更新后的代码(编译失败的部分标记为“旧”)
import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpResponse} from '@angular/common/http';
import {HttpHandler, HttpRequest, HttpErrorResponse} from '@angular/common/http';
/*
OLD:
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/do';
*/
import { Observable } from 'rxjs';
import { of } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { AuthService } from './auth.service';
@Injectable()
export class StockAppInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.authService.authToken) {
const authReq = req.clone({
headers: req.headers.set(
'Authorization',
this.authService.authToken
)
});
console.log('Making an authorized request');
req = authReq;
}
/*
* OLD:
* return next.handle(req)
* .do(event => this.handleResponse(req, event),
* error => this.handleError(req, error));
*/
return next.handle(req).pipe(
tap(
event => this.handleResponse(req, event),
error => this.handleError(req, error)
)
);
}
handleResponse(req: HttpRequest<any>, event) {
console.log('Handling response for ', req.url, event);
if (event instanceof HttpResponse) {
console.log('Request for ', req.url,
' Response Status ', event.status,
' With body ', event.body);
}
}
handleError(req: HttpRequest<any>, event) {
console.error('Request for ', req.url,
' Response Status ', event.status,
' With error ', event.error);
}
}
所需的更改包括更改import
路径以及替换pipe()
,tap()
和of()
。
此链接也是RxJS6更改的好资源:
https://www.academind.com/learn/javascript/rxjs-6-what-changed/
答案 3 :(得分:3)
在rxjs 6中,“ do”运算符已替换为“ tap”运算符,这就是为什么 发生此错误“类型上不存在属性“ do” 'Observable
'“ 要解决此错误,您有两个选择
解决方案1:修补您的代码...可以与do运算符一起正常工作
npm install rxjs-compat@6 --save
解决方案2:将您的 next.handle 代码替换为以下代码
return next.handle(req).pipe(
tap(
event => this.handleResponse(req, event),
error => this.handleError(req, error)
)
);