Angular HTTP GET with TypeScript error http.get(…)

2018-12-31 05:41发布

I have a problem with HTTP in Angular.

I just want to GET a JSON list and show it in the view.

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

And in the HallListComponent I call the getHalls method from the service:

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

However, I got an exception:

TypeError: this.http.get(...).map is not a function in [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"
  ]
}

标签: angular rxjs
17条回答
忆尘夕之涩
2楼-- · 2018-12-31 05:41

For Angular versions 5 and above, the updated importing line looks like :

import { map } from 'rxjs/operators';

OR

import { map } from 'rxjs/operators';

Also these versions totally supports Pipable Operators so you can easily use .pipe() and .subscribe().

If you are using Angular version 2, then the following line should work absolutely fine :

import 'rxjs/add/operator/map';

OR

import 'rxjs/add/operators/map';

If you still encounter a problem then you must go with :

import 'rxjs/Rx';

I won't prefer you to use it directly bcoz it boosts the Load time, as it has a large number of operators in it (useful and un-useful ones) which is not a good practice according to the industry norms, so make sure you try using the above mentioned importing lines first, and if that not works then you should go for rxjs/Rx

查看更多
有味是清欢
3楼-- · 2018-12-31 05:42

Using Observable.subscribe directly should work.

@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()); // <<--
    }
}
查看更多
何处买醉
4楼-- · 2018-12-31 05:43

I think that you need to import this:

import 'rxjs/add/operator/map'

Or more generally this if you want to have more methods for observables. WARNING: This will import all 50+ operators and add them to your application, thus affecting your bundle size and load times.

import 'rxjs/Rx';

See this issue for more details.

查看更多
孤独寂梦人
5楼-- · 2018-12-31 05:43

With Angular 5 the RxJS import is improved.

Instead of

import 'rxjs/add/operator/map';

We can now

import { map } from 'rxjs/operators';
查看更多
有味是清欢
6楼-- · 2018-12-31 05:43

Just add the line in you file,

import 'rxjs/Rx';

It will import bunch of dependencies.Tested in angular 5

查看更多
旧时光的记忆
7楼-- · 2018-12-31 05:45

The map you using here, is not the .map() in javascript, it's Rxjs map function which working on Observables in Angular...

So in that case you need to import it if you'd like to use map on the result data...

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.

So simply import it like this:

import 'rxjs/add/operator/map';
查看更多
登录 后发表回答