Angular 2 HTTP GET与TypeScript错误http.get(…).map不是中的函数
我在Angular 2
遇到了HTTP问题。
我只想GET
一个JSON
列表并在视图中显示它。
服务类
import {Injectable} from "angular2/core"; import {Hall} from "./hall"; import {Http} from "angular2/http"; @Injectable() export class HallService { public http:Http; public static PATH:string = 'app/backend/' constructor(http:Http) { this.http=http; } getHalls() { return this.http.get(HallService.PATH + 'hall.json').map((res:Response) => res.json()); } }
在HallListComponent
我从服务中调用getHalls
方法:
export class HallListComponent implements OnInit { public halls:Hall[]; public _selectedId:number; constructor(private _router:Router, private _routeParams:RouteParams, private _service:HallService) { this._selectedId = +_routeParams.get('id'); } ngOnInit() { this._service.getHalls().subscribe((halls:Hall[])=>{ this.halls=halls; }); } }
不过,我得到了一个例外:
TypeError:this.http.get(…)。map不是[null]中的函数
霍尔center.component
import {Component} from "angular2/core"; import {RouterOutlet} from "angular2/router"; import {HallService} from "./hall.service"; import {RouteConfig} from "angular2/router"; import {HallListComponent} from "./hall-list.component"; import {HallDetailComponent} from "./hall-detail.component"; @Component({ template:` <h2>my app</h2> <router-outlet></router-outlet> `, directives: [RouterOutlet], providers: [HallService] }) @RouteConfig([ {path: '/', name: 'HallCenter', component:HallListComponent, useAsDefault:true}, {path: '/hall-list', name: 'HallList', component:HallListComponent} ]) export class HallCenterComponent{}
app.component
import {Component} from 'angular2/core'; import {ROUTER_DIRECTIVES} from "angular2/router"; import {RouteConfig} from "angular2/router"; import {HallCenterComponent} from "./hall/hall-center.component"; @Component({ selector: 'my-app', template: ` <h1>Examenopdracht Factory</h1> <a [routerLink]="['HallCenter']">Hall overview</a> <router-outlet></router-outlet> `, directives: [ROUTER_DIRECTIVES] }) @RouteConfig([ {path: '/hall-center/...', name:'HallCenter',component:HallCenterComponent,useAsDefault:true} ]) export class AppComponent { }
tsconfig.json
{ "compilerOptions": { "target": "ES5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false }, "exclude": [ "node_modules" ] }
对不起,很长的post…
我认为你需要导入这个:
import 'rxjs/add/operator/map'
或者更一般地说,如果你想有更多的观测方法。 警告:这将导入所有50+运营商,并将其添加到您的应用程序,从而影响您的包的大小和加载时间。
import 'rxjs/Rx';
看到这个问题的更多细节。
只是一些背景…新的服务器通信开发指南(最后)讨论/提到/解释这个:
RxJS库很大。 在构build生产应用程序并将其部署到移动设备时,大小很重要。 我们应该只包括我们实际需要的那些function。
因此,Angular在
rxjs/Observable
模块中公开了Observable
的精简版本,这个版本缺less几乎所有的运算符,包括我们想在这里使用的运算符,比如map
方法。我们需要添加我们所需的操作员。 我们可以逐个添加每个运算符,直到我们有一个自定义的Observable实现被精确调整到我们的要求。
正如@Thierry已经回答,我们可以拉我们需要的操作员:
import 'rxjs/add/operator/map'; import 'rxjs/operator/delay'; import 'rxjs/operator/mergeMap'; import 'rxjs/operator/switchMap';
或者,如果我们懒惰,我们可以拉入全套的运营商。 警告:这将添加所有50+运营商到您的应用程序包,并会影响加载时间
import 'rxjs/Rx';
直接使用Observable.subscribe
应该工作。
@Injectable() export class HallService { public http:Http; public static PATH:string = 'app/backend/' constructor(http:Http) { this.http=http; } getHalls() { // ########### No map return this.http.get(HallService.PATH + 'hall.json'); } } export class HallListComponent implements OnInit { public halls:Hall[]; / *** / ngOnInit() { this._service.getHalls() .subscribe(halls => this.halls = halls.json()); // <<-- } }
由于angular2中的 Http服务返回一个Observabletypes,从你的Angular2安装目录(在我的例子中是'node_modules'),我们需要使用http服务在你的组件中导入Observable的map函数,如下所示:
import 'rxjs/add/operator/map';
您在这里使用的地图不是JavaScript中的.map()
,它是Rxjs地图函数,它在Angular中的Observables
上工作…
所以在这种情况下,如果您想在结果数据上使用地图,则需要导入它…
map(project: function(value: T, index: number): R, thisArg: any): Observable<R>
将给定的项目函数应用于源Observable发出的每个值,并将结果值作为Observable发送。
所以简单地像这样导入它:
import 'rxjs/add/operator/map';
使用Angular 5,RxJS导入function得到了改进。
代替
import 'rxjs/add/operator/map';
我们现在可以
import { map } from 'rxjs/operators';
诚然,RxJs已经将它的映射运算符分离到一个单独的模块中,现在您需要像其他运算符一样明确地导入它。
import rxjs/add/operator/map;
你会没事的