嗨,我正在尝试学习有关 Angular 的教程,但该教程是在 9 月份制作的。我相信这个人使用了 angular-cli 1.3.2。我不确定他使用的是哪个版本的 rxjs。我正在使用 Angular cli 6.0.0 和 Angular 6 以及 rxjs 6.1.0。
我遇到了一个问题,找不到在 observable 上调用 .map 。
ERROR in xxx/xxx/dataService.ts(19,14): error TS2339: Property 'map' does not exist on type 'Observable<Object>'.
我查看了 Observable 类,但没有看到名为 map 的函数。
Angular 6 或 rxjs 中是否有一种新方法来实现教程想要实现的目标?
这是我的 .ts 文件:
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { map } from 'rxjs/operators';
@Injectable()
export class DataService {
constructor(private http: HttpClient) {
}
public products = [
];
loadProducts() {
return this.http.get("/api/products")
.map((data: any[]) => {
this.products = data;
return true;
});
}
}
这是
ng --version
的输出
λ ng --version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 6.0.0
Node: 8.11.1
OS: win32 x64
Angular: 6.0.0
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.6.0
@angular-devkit/build-angular 0.6.0
@angular-devkit/build-optimizer 0.6.0
@angular-devkit/core 0.6.0
@angular-devkit/schematics 0.6.0 (cli-only)
@ngtools/webpack 6.0.0
@schematics/angular 0.6.0 (cli-only)
@schematics/update 0.6.0 (cli-only)
rxjs 6.1.0
typescript 2.7.2
webpack 4.6.0
我做了一些挖掘,在我的node_modules/rxjs/observable文件夹中没有map.*文件
λ ls -R rxjs\observable
'rxjs\observable':
ArrayLikeObservable.d.ts IfObservable.d.ts combineLatest.d.ts if.js.map
ArrayLikeObservable.js IfObservable.js combineLatest.js interval.d.ts
ArrayLikeObservable.js.map IfObservable.js.map combineLatest.js.map interval.js
ArrayObservable.d.ts IntervalObservable.d.ts concat.d.ts interval.js.map
ArrayObservable.js IntervalObservable.js concat.js merge.d.ts
ArrayObservable.js.map IntervalObservable.js.map concat.js.map merge.js
BoundCallbackObservable.d.ts IteratorObservable.d.ts defer.d.ts merge.js.map
BoundCallbackObservable.js IteratorObservable.js defer.js never.d.ts
BoundCallbackObservable.js.map IteratorObservable.js.map defer.js.map never.js
BoundNodeCallbackObservable.d.ts NeverObservable.d.ts dom/ never.js.map
BoundNodeCallbackObservable.js NeverObservable.js empty.d.ts of.d.ts
BoundNodeCallbackObservable.js.map NeverObservable.js.map empty.js of.js
ConnectableObservable.d.ts PairsObservable.d.ts empty.js.map of.js.map
ConnectableObservable.js PairsObservable.js forkJoin.d.ts onErrorResumeNext.d.ts
ConnectableObservable.js.map PairsObservable.js.map forkJoin.js onErrorResumeNext.js
DeferObservable.d.ts PromiseObservable.d.ts forkJoin.js.map onErrorResumeNext.js.map DeferObservable.js PromiseObservable.js from.d.ts pairs.d.ts
DeferObservable.js.map PromiseObservable.js.map from.js pairs.js
EmptyObservable.d.ts RangeObservable.d.ts from.js.map pairs.js.map
EmptyObservable.js RangeObservable.js fromArray.d.ts race.d.ts
EmptyObservable.js.map RangeObservable.js.map fromArray.js race.js
ErrorObservable.d.ts ScalarObservable.d.ts fromArray.js.map race.js.map
ErrorObservable.js ScalarObservable.js fromEvent.d.ts range.d.ts
ErrorObservable.js.map ScalarObservable.js.map fromEvent.js range.js
ForkJoinObservable.d.ts SubscribeOnObservable.d.ts fromEvent.js.map range.js.map
ForkJoinObservable.js SubscribeOnObservable.js fromEventPattern.d.ts throw.d.ts
ForkJoinObservable.js.map SubscribeOnObservable.js.map fromEventPattern.js throw.js
FromEventObservable.d.ts TimerObservable.d.ts fromEventPattern.js.map throw.js.map
FromEventObservable.js TimerObservable.js fromIterable.d.ts timer.d.ts
FromEventObservable.js.map TimerObservable.js.map fromIterable.js timer.js
FromEventPatternObservable.d.ts UsingObservable.d.ts fromIterable.js.map timer.js.map
FromEventPatternObservable.js UsingObservable.js fromPromise.d.ts using.d.ts
FromEventPatternObservable.js.map UsingObservable.js.map fromPromise.js using.js
FromObservable.d.ts bindCallback.d.ts fromPromise.js.map using.js.map
FromObservable.js bindCallback.js generate.d.ts zip.d.ts
FromObservable.js.map bindCallback.js.map generate.js zip.js
GenerateObservable.d.ts bindNodeCallback.d.ts generate.js.map zip.js.map
GenerateObservable.js bindNodeCallback.js if.d.ts
GenerateObservable.js.map bindNodeCallback.js.map if.js
'rxjs\observable/dom':
AjaxObservable.d.ts AjaxObservable.js.map WebSocketSubject.js ajax.d.ts ajax.js.map webSocket.js
AjaxObservable.js WebSocketSubject.d.ts WebSocketSubject.js.map ajax.js webSocket.d.ts webSocket.js.map
在
rxjs@6
中,您可以使用 from 作为独立函数:
import { from } from 'rxjs';
另请参阅迁移到 rxjs6 指南
https://github.com/ReactiveX/rxjs/blob/master/docs_app/content/guide/v6/migration.md#import-paths
更新
您需要切换到管道语法,确保导入从 rxjs/operators 使用的所有运算符。例如:
import { map, filter, catchError, mergeMap } from 'rxjs/operators';
pipe
是Observable上的一个方法,用于组合运算符
以下是如何使用版本 6 中的新方法
pipe()
:
loadProducts() {
return this.http.get("/api/products").
pipe(
map((data: any[]) => {
this.products = data;
return true;
}), catchError( error => {
return throwError( 'Something went wrong!' )
});
)
}
请记住,在版本 6 中,您现在应该使用
catchError
和 throwError
,而不是: catch
和 throw
。这是版本 6 的正确导入:
import { Observable, of, throwError, ...} from "rxjs"
import { map, catchError, ...} from "rxjs/operators"
你必须更改为管道语法:
import { Http } from '@angular/http';
import { Injectable } from '@angular/core';
import {map, catchError} from "rxjs/operators";
import { Observable, throwError } from 'rxjs';
list():Observable<any>{
return this.http.get(this.url)
.pipe(
map((e:Response)=> e.json()),
catchError((e:Response)=> throwError(e))
);
}
只需更改导入地图的方式即可
import { map } from "rxjs/operators";
然后使用带地图的管道。请参阅示例以更好地理解
import {Http,Headers,Response} from '@angular/http';
import { map } from "rxjs/operators";
@Injectable({
providedIn: 'root'
})
export class ContactServiceService {
constructor(private http:Http) { }
getContactList(){
return this.http.get('http://localhost:3000/contact')
.pipe(map(res => res.json()));
}
}
Angular新版本实际上不支持.map。新的 Angular 版本进行了一些更改。您可以通过访问 Angular 网站来检查这些问题,但这里是这些问题的解决方案;运行这些命令 项目的 cmd 目的地:
npm install --save rxjs-compat
并享受旧技术,但不要忘记在共享服务中添加这些行:
import { Observable, Subject } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
由于某些不明原因
rxjs-compat
有时不会自动拾取,您可以自己导入它,例如polyfills.ts
:
import 'rxjs-compat';
在带有 rxjs 6.3.3 的 Angular 6x 中,你可以做到这一点。在文件(app.component.ts)中
import { Component } from '@angular/core';
import { HttpClient, HttpParams, HttpHeaders} from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map, catchError, retry } from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
_url = 'http://...';
constructor( private http: HttpClient ) { }
articles: Observable<any>;
// Method to get info
getAPIRest() {
const params = new HttpParams().set('parameter', 'value');
const headers = new HttpHeaders().set('Autorization', 'auth-token');
this.articles = this.http.get(this._url + '/articles', { params, headers })
.pipe( retry(3),
map((data => data),
catchError(err => throwError(err))));
}
}