带有 TypeScript 错误的 Angular HTTP GET http.get(...).map 不是 [null] 中的函数
Posted
技术标签:
【中文标题】带有 TypeScript 错误的 Angular HTTP GET http.get(...).map 不是 [null] 中的函数【英文标题】:Angular HTTP GET with TypeScript error http.get(...).map is not a function in [null] 【发布时间】:2016-04-03 13:56:30 【问题描述】:我在 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] 中的函数
大厅中心组件
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"
]
【问题讨论】:
http.get 不返回一个承诺吗? @bmm6o 新的Http
服务返回一个 observable
我遇到了一个几乎相同的问题,试图将项目从 Angular2 beta-17 迁移到最终版本。对我来说,问题是我的 IDE,使用 VS 2015,Update 3。TypeScript 语言服务扩展仍然在1.8.36
,而 ng2 快速入门指南(在我写这篇文章时)使用的是"typescript": "^2.0.2"
。升级 TS 语言。通过扩展和更新提供的服务对我有用。在安装该更新时,我遇到了this SO answer,它以相同的结论结束。
对于phpstorm/webstorm,用我项目的库更新typescript版本也解决了这个问题。我遵循了这个 SO 答案的步骤:***.com/a/31608934/1291428
【参考方案1】:
我认为你需要导入这个:
import 'rxjs/add/operator/map'
或者更一般地说,如果您想为可观察对象提供更多方法。 警告:这将导入所有 50 多个运算符并将它们添加到您的应用程序中,从而影响您的包大小和加载时间。
import 'rxjs/Rx';
更多详情请见this issue。
【讨论】:
哪些错误仍然存在?您可以在 *** 上提出一些与此相关的具体问题 ;-) 这个问题也可能对您有所帮助:***.com/questions/34450131/…. 从 Angular 2 RC 0 开始,这不再是必需的。 @OnurYıldırım,使用 rc.4,仍然需要此导入,除非我做错了什么。 请不要使用'import 'rxjs/Rx';'因为它导入了所有东西,而且 rxjs 往往很大。根据需要一一导入操作符。 Angular 2 与 rxjs:5.0.0-beta.12 在这里。我仍然必须import 'rxjs/add/operator/do'
...虽然我们不必再为.map()
这样做了。但这有助于我的.do()
案例,让我意识到我特别需要导入它。谢谢!我投了一票:)【参考方案2】:
只是一些背景... 新创建的Server Communication 开发指南(最后)讨论/提及/解释了这一点:
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';
【讨论】:
导入'rxjs/Rx';哇。我所有的头发都立即消失了。我不敢相信这不是为 Rxjs/Angular2 打印在世界各地的。谢谢!!! 但它通常不会 lint,默认情况下它是列入黑名单的导入。创建一个新的 Angular CLI 项目,你会看到。我自己也喜欢这种便利,但我在纽约工作的地方的惯例是不这样做。【参考方案3】:从 rxjs 5.5 开始,你可以使用 pipeable 操作符
import map from 'rxjs/operators';
有什么问题 import 'rxjs/add/operator/map';
当我们使用这种方法时,map
运算符将被修补为observable.prototype
并成为该对象的一部分。
如果稍后,您决定从处理可观察流的代码中删除 map
运算符但未能删除相应的导入语句,则实现 map
的代码仍然是 Observable.prototype
的一部分。
当打包程序试图消除未使用的代码(aka tree shaking
)时,他们可能会决定将 map
运算符的代码保留在 Observable 中,即使它没有在 Observable 中使用。应用。
解决方案 - Pipeable operators
Pipeable 运算符是纯函数,不会修补 Observable。您可以使用 ES6 导入语法 import map from "rxjs/operators"
导入运算符,然后将它们包装到一个函数 pipe()
中,该函数采用可变数量的参数,即可链接的运算符。
类似这样的:
getHalls()
return this.http.get(HallService.PATH + 'hall.json')
.pipe(
map((res: Response) => res.json())
);
【讨论】:
是的,现在使用 Rxjs 版本 7+,建议通过使用管道来使用可管道运算符,很好的一个,我发现所有以前的答案都是旧的,并且没有更新到当前版本的 Angular 和 Rxjs 【参考方案4】:Angular 5 改进了 RxJS 导入。
代替
import 'rxjs/add/operator/map';
我们现在可以
import map from 'rxjs/operators';
【讨论】:
使用这种方法,现在在你的构建中它只会包含使用过的操作符(在这种情况下是 map),之前它包含了 rxjs 库中的所有操作符。查看下面的链接了解更多详情。 loiane.com/2017/08/angular-rxjs-imports【参考方案5】:直接使用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()); // <<--
【讨论】:
这不是一个非常有效的方法。例如,如果有多个订阅者,他们每个人都必须在数据上运行 map,而不是只在服务中执行一次。我认为 OP 有正确的方法,只是没有加载正确的模块来使用它。【参考方案6】:对于 Angular 5 及更高版本,更新后的导入行如下所示:
import map from 'rxjs/operators';
或
import map from 'rxjs/operators';
此外,这些版本完全支持 Pipable Operators,因此您可以轻松使用 .pipe() 和 .subscribe()。
如果您使用的是 Angular 版本 2,那么以下行应该可以正常工作:
import 'rxjs/add/operator/map';
或
import 'rxjs/add/operators/map';
如果你仍然遇到问题,那么你必须去:
import 'rxjs/Rx';
我不希望你直接使用它,因为它会增加加载时间,因为它有大量的运算符(有用的和无用的),根据行业规范,这不是一个好的做法,所以请确保您首先尝试使用上述导入行,如果这不起作用,那么您应该使用 rxjs/Rx
【讨论】:
【参考方案7】:我有办法解决这个问题
安装这个包:
npm install rxjs@6 rxjs-compat@6 --save
然后导入这个库
import 'rxjs/add/operator/map'
最后重启你的 ionic 项目然后
ionic serve -l
【讨论】:
【参考方案8】:您在这里使用的 map 不是 javascript 中的 .map()
,它是 Rxjs 映射函数,它在 Angular 中作用于 Observables
...
所以在这种情况下,如果您想在结果数据上使用地图,则需要导入它...
map(project: function(value: T, index: number): R, thisArg: any): Observable<R>
将给定的项目函数应用于每个发出的值 由源 Observable 发出,并将结果值作为 可观察。
所以只需像这样导入它:
import 'rxjs/add/operator/map';
【讨论】:
【参考方案9】:Angular 版本 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
imports: [
HttpModule,
BrowserModule,
FormsModule,
RouterModule.forRoot(appRoutes)
],
第二个使用地图你应该首先导入管道:
import pipe from 'rxjs';
第三个你需要从地图函数导入:
import map from 'rxjs/operators';
你必须像这个例子一样在管道内使用地图:
constructor(public http:Http)
getusersGET()
return this.http.get('http://jsonplaceholder.typicode.com/users').pipe(
map(res => res.json() ) );
效果很好,祝你好运!
【讨论】:
【参考方案10】:由于 angular2 中的 Http 服务返回一个 Observable 类型, 从你的Angular2安装目录(在我的例子中是'node_modules'),我们需要使用http服务在你的组件中导入Observable的map函数,如:
import 'rxjs/add/operator/map';
【讨论】:
【参考方案11】:Angular 6 - 只有 import 'rxjs/Rx' 对我有用
【讨论】:
【参考方案12】:只需在文件中添加该行,
导入'rxjs/Rx';
它将导入一堆依赖项。在 Angular 5 中测试
【讨论】:
【参考方案13】:没错,RxJs 已将其 map 运算符分离到一个单独的模块中,现在您需要像任何其他运算符一样显式导入它。
import rxjs/add/operator/map;
你会没事的。
【讨论】:
【参考方案14】:全局导入是安全的。
导入'rxjs/Rx';
【讨论】:
【参考方案15】:import 'rxjs/add/operator/map';
将解决您的问题
我在 Angular 5.2.0 和 rxjs 5.5.2 中对其进行了测试
【讨论】:
【参考方案16】:发生这种情况是因为您正在使用 rxjs 并且在 rxjs 中的函数不是静态的,这意味着您不能直接调用它们,您必须调用管道内的方法并从 rxjs 库中导入该函数
但是如果你使用的是 rxjs-compat 那么你只需要导入 rxjs-compat 操作符
【讨论】:
【参考方案17】:我尝试了以下命令,它得到了修复:
npm install rxjs@6 rxjs-compat@6 --save
import 'rxjs/Rx';
【讨论】:
这只是为了让您在 rxjs 6 中通过为您执行一些修补程序开始工作。这只是一个短期修复,应该进行完整的 rxjs 6 转换。【参考方案18】:从 'rxjs/operators' 导入 map ;
这在角度 8 中对我有用
【讨论】:
【参考方案19】:加上 @mlc-mapis 评论的内容,您正在混合 lettable 运算符和原型修补方法。使用一个或另一个。
你的情况应该是
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
【讨论】:
以上是关于带有 TypeScript 错误的 Angular HTTP GET http.get(...).map 不是 [null] 中的函数的主要内容,如果未能解决你的问题,请参考以下文章
带有 TypeScript 错误的 Angular HTTP GET http.get(...).map 不是 [null] 中的函数
如何显示来自 angular 8 typescript 订阅的错误消息?
带有 Typescript 错误 TS18003 的 Npm 服务器