带有 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】:

您在这里使用的 ma​​p 不是 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 2 Typescript 编译错误

如何显示来自 angular 8 typescript 订阅的错误消息?

带有 Typescript 错误 TS18003 的 Npm 服务器

带有 TypeScript 的 Angular 2 [关闭]

带有 TypeScript 的 Angular 4:通过引用传递参数