Angular HTTP GET带有TypeScript错误HTTP . GET(…)。Map不是[null]中的函数

我在Angular中的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]中的函数

hall-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"
]
}
264185 次浏览

我认为你需要导入这个:

import 'rxjs/add/operator/map'

或者更一般地说,如果你想有更多的方法用于可观察对象。 警告:这将导入所有50+操作符并将它们添加到你的应用程序中,从而影响你的bundle大小和加载时间

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()); // <<--
}
}

只是一些背景知识……新创建的服务器通信开发指南(最后)讨论/提到/解释了这一点:

RxJS库相当大。当我们构建生产应用程序并将其部署到移动设备时,大小很重要。我们应该只包含那些我们真正需要的特性。

因此,Angular在rxjs/Observable模块中公开了一个精简版的Observable,这个版本几乎缺少所有的操作符,包括我们在这里想要使用的map方法。

由我们来添加我们需要的运算符。我们可以一个接一个地添加每个操作符,直到我们有一个定制的Observable实现精确地调整到我们的需求。

所以正如@Thierry已经回答的那样,我们可以只引入我们需要的操作符:

import 'rxjs/add/operator/map';
import 'rxjs/operator/delay';
import 'rxjs/operator/mergeMap';
import 'rxjs/operator/switchMap';

或者,如果我们懒得,我们可以引入完整的操作符集。警告:这将添加所有50+运营商到你的应用程序包,并将影响加载时间

import 'rxjs/Rx';
由于angular2中的Http服务返回可观测的类型, 从你的Angular2安装目录(在我的例子中是'node_modules'),我们需要使用http服务在你的组件中导入Observable的映射函数,如下
import 'rxjs/add/operator/map';

你在这里使用的地图不是JavaScript中的.map(),而是Rxjs的map函数,它在Angular中的Observables上工作。

在这种情况下,你需要导入它如果你想在结果数据上使用map。

map(project: function(value: T, index: number): R, thisArg: any): Observable<R>将给定的项目函数应用于每个发出的值 ,并将结果值作为 可见。< / p >

所以像这样简单地导入它:

import 'rxjs/add/operator/map';

没错,RxJs已经在一个单独的模块中分离了它的map操作符,现在你需要像任何其他操作符一样显式导入它。

import rxjs/add/operator/map;

你会没事的。

在Angular 5中,RxJS导入得到了改进。

而不是

import 'rxjs/add/operator/map';

我们现在可以

import { map } from 'rxjs/operators';

全球进口是安全的。

进口“rxjs / Rx”;

import 'rxjs/add/operator/map';

会解决你的问题

我在angular 5.2.0和rxjs 5.5.2中测试了它

对于Angular 5及以上版本,更新后的导入行看起来是这样的:

import { map } from 'rxjs/operators';

import { map } from 'rxjs/operators';

此外,这些版本完全支持Pipable操作符,因此您可以轻松使用.pipe()和.subscribe()。

如果你使用的是Angular版本2,那么下面这行代码应该可以正常工作:

import 'rxjs/add/operator/map';

import 'rxjs/add/operators/map';

如果你仍然遇到问题,那么你必须这样做:

import 'rxjs/Rx';

我不喜欢你直接使用它,因为它增加了加载时间,因为它有大量的操作符(有用的和无用的),这不是一个好的实践,根据行业规范,所以一定要先尝试使用上面提到的导入行,如果这不起作用,那么你应该去rxjs/Rx

我有一个解决这个问题的办法

安装此包:

npm install rxjs@6 rxjs-compat@6 --save

然后导入这个库

import 'rxjs/add/operator/map'

最后重新启动你的离子计划

ionic serve -l

rxjs 5.5开始,你可以使用pipeable操作符

import { map } from 'rxjs/operators';

有什么问题吗 import 'rxjs/add/operator/map';

当我们使用这种方法时,map操作符将被修补到observable.prototype并成为该对象的一部分。

如果稍后,你决定从处理可观察流的代码中删除map操作符,但未能删除相应的导入语句,则实现map的代码仍然是Observable.prototype的一部分。

当捆绑者试图消除未使用的代码(选择。 tree shaking)时,他们可能会决定在可观察对象中保留map操作符的代码,即使它没有在应用程序中使用。

__abc1 - __abc0

Pipeable操作符是纯函数,不修补可观测的。您可以使用ES6导入语法import { map } from "rxjs/operators"导入操作符,然后将它们包装到函数pipe()中,该函数接受可变数量的参数,即可链操作符。

就像这样:

getHalls() {
return this.http.get(HallService.PATH + 'hall.json')
.pipe(
map((res: Response) => res.json())
);
}

Angular 6——只有import 'rxjs/Rx'对我有用

只要在你的文件里加上这行,

import 'rxjs/Rx';

它会导入一堆依赖项。在angular 5中测试

这是因为你正在使用RXJS,在RXJS函数不是静态的,这意味着你不能直接调用它们,你必须调用管道内的方法,并从RXJS库导入该函数

但是如果你正在使用rxjs-compat,那么你只需要导入rxjs-compat操作符

Angular version 6 "0.6.8" RXJS版本6 "^6.0.0"

此解决方案适用于:

  "@angular-devkit/core": "0.6.8",
"rxjs": "^6.0.0"
我们都知道angular每天都在开发,所以每天都有很多变化,这个解决方案适用于angular 6和RXJS 6
首先要使用HTTP,你应该导入它从: 毕竟你必须在app.module.ts

中声明HttpModule
import { Http } from '@angular/http';

你必须将HttpModule添加到Ngmodule -> 进口

  imports: [
HttpModule,
BrowserModule,
FormsModule,
RouterModule.forRoot(appRoutes)
],

第二,使用map,你应该首先导入管道:

import { pipe } from 'rxjs';

第三,你需要从下面导入map函数:

import { map } from 'rxjs/operators';

你必须像下面这个例子一样在管道中使用map:

 constructor(public http:Http){  }


getusersGET(){
return this.http.get('http://jsonplaceholder.typicode.com/users').pipe(
map(res => res.json()  )  );
}

那太好了祝你好运!

我尝试了下面的命令,它得到了修复:

npm install rxjs@6 rxjs-compat@6 --save




import 'rxjs/Rx';

Import {map} from 'rxjs/operators';

这适用于我的angular 8

加上@mlc-mlapis所评论的,您混合了可让操作符和原型修补方法。使用其中之一

对你的案子来说应该是

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';


@Injectable()
export class SwPeopleService {
people$ = this.http.get('https://swapi.co/api/people/')
.map((res:any) => res.results);


constructor(private http: HttpClient) {}
}

https://stackblitz.com/edit/angular-http-observables-9nchvz?file=app%2Fsw-people.service.ts