我在Angular中的HTTP有一个问题。

我只是想获得一个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"
  ]
}

当前回答

你在这里使用的映射不是JavaScript中的.map(),而是Rxjs的map函数,它在Angular中的可观察对象上工作。

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

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

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

import 'rxjs/add/operator/map';

其他回答

Angular 6——只有导入'rxjs/Rx'才管用

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

安装此包:

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

然后导入这个库

import 'rxjs/add/operator/map'

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

ionic serve -l

使用可观察到的。直接订阅应该有用。

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

加上@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

从rxjs 5.5开始,你可以使用可管道操作符

import { map } from 'rxjs/operators';

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

当我们使用这个方法时,map操作符将被修补到可观察对象。原型并成为该对象的一部分。

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

当捆绑者试图消除未使用的代码(也就是摇树)时,他们可能会决定在Observable中保留map操作符的代码,即使它没有在应用程序中使用。

解决方案-可管道操作符

可管道操作符是纯函数,不会给Observable打补丁。你可以使用ES6的import语法import {map}从"rxjs/operators"导入操作符,然后将它们包装到一个函数pipe()中,该函数pipe()接受可变数量的参数,即可链操作符。

就像这样:

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