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);
}
}
何か案が?
問題はangularではなく、rxjsにあります。 rxjsは、rxjsバージョン6からの重大な変更を導入しました。
コードを変更せずにコードを再び機能させるには、次のパッケージをインストールします。
npm install rxjs-compat@6 --save
その後、プロジェクトをコンパイルできるはずです。 rxjs-compat
は一時的な解決策であるため、新しいバージョンで動作するようにコードベースを更新する必要があります。
更新する必要があるもの:
インポートステートメントを更新
import { Observable } from "rxjs/Observable";
to
import { Observable } from "rxjs";
オペレーターのインポートを更新します
import 'rxjs/add/operator/do'
to
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);
Rxjs 6はいくつかの重大な変更を導入し、「do」演算子は「tap」演算子に置き換えられました( 'rxjs/internal/operators
'から)。
New演算子を使用してコードをリファクタリングするか、下位互換性(npm install --save rxjs-compat
)のためにrxjs-compatライブラリを追加することにより、古い 'do'構文を引き続き使用できます。
RxJs 6の前に、「do」演算子をインポートする必要があることに注意してください。
import 'rxjs/add/operator/do';
詳細はこちら TypeScriptエラーhttp.get(...)。mapのあるHTTP GETは[null]の関数ではありません
Angular/rxjs7 ++で導入された「重大な変更」を解決する方法に関するTjaart van der Waltの応答に感謝します。しかし、Angularインターセプターに彼の応答を適用しようとすると、いくつかの問題がまだ発生しました。
更新されたコードは次のとおりです(コンパイルに失敗したセクションは「OLD」とマークされています)
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/