wake-up-neo.com

Angular HTTP GET mit TypeScript-Fehler http.get (...). Map ist keine Funktion in [null]

Ich habe ein Problem mit HTTP in Angular. 

Ich möchte nur GET eine JSON Liste auflisten und in der Ansicht anzeigen. 

Serviceklasse

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

Und in der HallListComponent rufe ich die getHalls-Methode vom Dienst auf:

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

Ich bekam jedoch eine Ausnahme: 

TypeError: this.http.get (...). Map ist keine Funktion 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"
  ]
}
303
Claudiu

Ich denke, dass Sie das importieren müssen:

import 'rxjs/add/operator/map'

Oder generell, wenn Sie mehr Methoden für Observables haben möchten WARNUNG: Dadurch werden alle 50+ Operatoren importiert und zu Ihrer Anwendung hinzugefügt. Dies wirkt sich auf die Paketgröße und Ladezeiten aus.

import 'rxjs/Rx';

Siehe diese Ausgabe für weitere Details.

514

Nur ein paar Hintergründe ... Die neu geprägte Server Communication dev-Anleitung (endlich) erläutert/erwähnt/erklärt dies:

Die RxJS-Bibliothek ist ziemlich groß. Die Größe ist wichtig, wenn wir eine Produktionsanwendung erstellen und auf mobilen Geräten bereitstellen. Wir sollten nur die Funktionen enthalten, die wir tatsächlich benötigen.

Dementsprechend macht Angular eine abgespeckte Version von Observable im rxjs/Observable-Modul verfügbar, einer Version, der fast alle Operatoren fehlen, einschließlich derjenigen, die wir hier verwenden möchten, wie beispielsweise die map-Methode.

Es liegt an uns, die benötigten Operatoren hinzuzufügen. Wir können jeden Operator einzeln hinzufügen, bis wir eine benutzerdefinierte Observable-Implementierung haben, die genau auf unsere Anforderungen abgestimmt ist.

Da @Thierry bereits geantwortet hat, können wir einfach die benötigten Operatoren einholen:

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

Oder wenn wir faul sind, können wir alle Operatoren einbeziehen. WARNUNG: Dadurch werden alle 50+ Bediener zu Ihrem App-Paket hinzugefügt und die Ladezeiten werden beeinflusst.

import 'rxjs/Rx';
79
Mark Rajcok

Mit Angular 5 wird der RxJS-Import verbessert. 

Anstatt

import 'rxjs/add/operator/map';

Wir können jetzt

import { map } from 'rxjs/operators';
15
Claudiu

Ab rxjs 5.5 können Sie die Operatoren pipeable verwenden 

import { map } from 'rxjs/operators';

Was stimmt nicht mit dem import 'rxjs/add/operator/map';

Wenn wir diesen Ansatz verwenden, wird der map-Operator zu observable.prototype gepatcht und Teil dieses Objekts. 

Wenn Sie später den Operator map aus dem Code entfernen, der den beobachtbaren Stream verarbeitet, die entsprechende Importanweisung jedoch nicht entfernen kann, bleibt der Code, der map implementiert, ein Teil des Observable.prototype.

Wenn die Bundler versuchen, den nicht verwendeten Code (a.k.a.tree shaking) zu entfernen, entscheiden sie sich möglicherweise dafür, den Code des map-Operators in Observable zu behalten, auch wenn er nicht in der Anwendung verwendet wird.

Lösung - Pipeable operators

Pipeable - Operatoren sind reine Funktionen und patchen das Observable nicht. Sie können Operatoren mithilfe der ES6-Importsyntax import { map } from "rxjs/operators" importieren und sie dann in eine Funktion pipe() einschließen, die eine variable Anzahl von Parametern benötigt, d. H. Verkettbare Operatoren.

Etwas wie das:

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

Die direkte Verwendung von Observable.subscribe sollte funktionieren.

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

Angular Version 6 "0.6.8" Rxjs Version 6 "^ 6.0.0"

diese Lösung ist für:

  "@angular-devkit/core": "0.6.8",
  "rxjs": "^6.0.0"

wie wir alle wissen, wird Winkel jeden Tag entwickelt. Daher gibt es jeden Tag viele Änderungen, und diese Lösung ist für Winkel 6 und Rxjs 6
Zuerst mit http arbeiten, sollten Sie es importieren von: Schließlich müssen Sie das HttpModule in app.module.ts deklarieren

import { Http } from '@angular/http';

und Sie müssen HttpModule zu Ngmodule hinzufügen -> Importe  

  imports: [
    HttpModule,
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(appRoutes)
  ],

zweitens sollten Sie zuerst Pipe importieren: 

import { pipe } from 'rxjs';

drittens müssen Sie die Kartenfunktion importieren von: 

import { map } from 'rxjs/operators';

sie müssen die Karte im Rohr wie folgt verwenden: 

 constructor(public http:Http){  }

    getusersGET(){
        return this.http.get('http://jsonplaceholder.typicode.com/users').pipe(
         map(res => res.json()  )  );
    }

das funktioniert perfekt viel glück! 

4
nadir hamidou

Ich habe eine Lösung für dieses Problem 

Installieren Sie dieses Paket:

npm install [email protected] [email protected] --save

dann importieren Sie diese Bibliothek 

import 'rxjs/add/operator/map'

starten Sie dann Ihr Ionenprojekt neu 

ionic serve -l
3
divyajeet singh

Für Angular-Versionen 5 und höher sieht die aktualisierte Importlinie folgendermaßen aus:

import { map } from 'rxjs/operators';

ODER 

import { map } from 'rxjs/operators';

Auch diese Versionen unterstützen vollständig Pipe-fähige Operatoren, sodass Sie .pipe () und .subscribe () problemlos verwenden können.

Wenn Sie Angular Version 2 verwenden, sollte die folgende Zeile einwandfrei funktionieren:

import 'rxjs/add/operator/map';

ODER 

import 'rxjs/add/operators/map';

Wenn Sie immer noch ein Problem haben, müssen Sie Folgendes tun: 

import 'rxjs/Rx';

Ich ziehe es nicht vor, dass Sie es direkt verwenden, da es die Ladezeit erhöht, da es eine große Anzahl von Operatoren (nützliche und nicht nützliche) enthält, was gemäß den Industrienormen keine gute Praxis ist Sie versuchen zuerst, die oben genannten Importlinien zu verwenden, und wenn dies nicht funktioniert, sollten Sie sich für rxjs/Rx entscheiden

3
Jitendra Ahuja

Die map die Sie hier verwenden, ist nicht die .map() in Javascript, es ist die Rxjs-Map-Funktion, die an Observables in Angular arbeitet ...

In diesem Fall müssen Sie sie importieren, wenn Sie die Karte mit den Ergebnisdaten verwenden möchten ...

map(project: function(value: T, index: number): R, thisArg: any): Observable<R> Wendet eine gegebene Projektfunktion auf jeden ausgegebenen Wert an von der Quelle Observable und gibt die resultierenden Werte als .__ aus. Beobachtbar.

Also einfach so importieren:

import 'rxjs/add/operator/map';
2
Alireza

Fügen Sie einfach die Zeile in Ihre Datei ein,

importiere 'rxjs/Rx';

Es wird eine Reihe von Abhängigkeiten importieren. In Winkel 5 getestet

2
Mandeep Singh

Da Http service in angle2 einen Observable type, Zurückgibt, müssen Sie aus Ihrem Angular2-Installationsverzeichnis (in meinem Fall 'node_modules') die Map-Funktion des Observable in Ihr importieren Komponente Verwendung von http service als:

import 'rxjs/add/operator/map';
1
Amardeep Kohli

Angular 6 - nur Import 'rxjs/Rx' hat den Trick für mich gemacht

1
Shimi Avizmil

Der globale Import ist sicher.

importiere 'rxjs/Rx';

1
rut shah

dies geschieht, weil Sie die rxjs verwenden und die Funktion in rxjs nicht statisch ist. Sie können sie also nicht direkt aufrufen, sondern Sie müssen die Methoden in der Pipe aufrufen und diese Funktion aus der rxjs-Bibliothek importieren 

Wenn Sie jedoch rxjs-compat verwenden, müssen Sie nur die rxjs-compat-Operatoren importieren

0

Es stimmt, RxJs hat seinen Kartenoperator in einem separaten Modul getrennt. Nun müssen Sie ihn wie jeden anderen Operator explizit importieren.

import rxjs/add/operator/map;

und es wird dir gut gehen.

0
Piyush P
import 'rxjs/add/operator/map';

wird dein Problem lösen

Ich habe es in Winkel 5.2.0 und Rxjs 5.5.2 getestet

0
Mayank Bhardwaj

Ich habe die folgenden Befehle ausprobiert und es wurde behoben:

npm install [email protected] [email protected] --save


import 'rxjs/Rx';
0
Phan Hero