Angular 带有 TypeScript 错误的 HTTP GET http.get(...).map 不是 [null] 中的函数

Angular HTTP GET with TypeScript error http.get(...).map is not a function in [null]

我在 Angular 中遇到 HTTP 问题。

我只想 GET 一个 JSON 列表并在视图中显示它。

服务class

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 is not a function in [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"
  ]
}

我认为你需要导入这个:

import 'rxjs/add/operator/map'

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

import 'rxjs/Rx';

有关详细信息,请参阅 this issue

直接使用 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()); // <<--
    }
}

只是一些背景...新制作的 Server Communication 开发指南(最后)discusses/mentions/explains 这个:

The RxJS library is quite large. Size matters when we build a production application and deploy it to mobile devices. We should include only those features that we actually need.

Accordingly, Angular exposes a stripped down version of Observable in the rxjs/Observable module, a version that lacks almost all operators including the ones we'd like to use here such as the map method.

It's up to us to add the operators we need. We could add each operator, one-by-one, until we had a custom Observable implementation tuned precisely to our requirements.

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

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

或者,如果我们懒惰,我们可以引入全套运算符。 警告:这会将所有 50 多个运算符添加到您的应用程序包中,并且会影响加载时间

import 'rxjs/Rx';

因为 Http 服务在 angular2 returns 一个 Observable 类型, 从你的 Angular2 安装目录('node_modules' 在我的例子中),我们需要使用 http 在你的 component 中导入 Observable 的地图功能服务,如:

import 'rxjs/add/operator/map';

你在这里使用的 map,不是 javascript 中的 .map(),它是 Rxjs 映射函数,它在 Observables 上工作 Angular...

所以在这种情况下,如果您想在结果数据上使用地图,则需要导入它...

map(project: function(value: T, index: number): R, thisArg: any): Observable<R> Applies a given project function to each value emitted by the source Observable, and emits the resulting values as an Observable.

所以只需像这样导入它:

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 项目然后

ionic serve -l

rxjs 5.5 开始,您可以使用 pipeable 运算符

import { map } from 'rxjs/operators';

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

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

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

当打包者试图消除未使用的代码(a.k.a. tree shaking)时,他们可能会决定保留 [=13] 的代码=] 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())
    );
}

Angular 6 - 只有导入 'rxjs/Rx' 对我有用

只需在您的文件中添加行,

进口'rxjs/Rx';

它将在 angular 5

中导入一堆 dependencies.Tested

发生这种情况是因为您正在使用 rxjs 并且 rxjs 函数不是静态的,这意味着您不能直接调用它们,您必须调用管道内的方法并从 rxjs 库中导入该函数

但是如果您使用的是 rxjs-compat,那么您只需要导入 rxjs-compat 运算符

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 yo 应该从以下位置导入它: 毕竟你必须在 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()  )  );
    }

非常好,祝你好运!

我尝试了以下命令并得到修复:

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


import 'rxjs/Rx';

从'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