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

Lesezeit: 8 Minuten

Benutzeravatar von Claudiu Matei
Claudius Matei

Ich habe ein Problem mit HTTP in Angular.

ich möchte einfach GET a JSON 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 Ich nenne die getHalls Methode aus dem Dienst:

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

Allerdings habe ich eine Ausnahme:

TypeError: this.http.get(…).map ist keine Funktion in [null]

Halle-Mitte.Komponente

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: "https://stackoverflow.com/",         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"
  ]
}

  • Gibt http.get kein Versprechen zurück?

    – bmm6o

    29. Dezember 2015 um 16:38 Uhr

  • @bmm6o Das Neue Http service gibt ein Observable zurück

    – Brocko

    29. Dezember 2015 um 16:39 Uhr

  • Ich bin auf ein fast identisches Problem gestoßen, als ich versuchte, ein Projekt von Angular2 Beta-17 auf die endgültige Version zu migrieren. Das Problem für mich war jedoch meine IDE, die VS 2015, Update 3, verwendet. Die TypeScript-Sprachdiensterweiterung war noch vorhanden 1.8.36wohingegen als ng2 die Schnellstartanleitung (während ich dies schreibe) verwendet wird "typescript": "^2.0.2". Upgrade der TS-Sprache. Service über Erweiterungen und Updates hat bei mir ausgereicht. Während dieses Update installiert wurde, stieß ich auf diese SO-Antwort, die mit der gleichen Schlussfolgerung endet.

    – Eric Lease

    21. September 2016 um 7:03 Uhr

  • Für phpstorm/webstorm löste auch das Aktualisieren der Typoskript-Version mit der Bibliothek meines Projekts das Problem. Ich habe die Schritte dieser SO-Antwort befolgt: stackoverflow.com/a/31608934/1291428

    – Sebas

    11. Dezember 2016 um 15:20 Uhr


Benutzeravatar von Thierry Templier
Thierry Templer

Ich denke, dass Sie dies importieren müssen:

import 'rxjs/add/operator/map'

Oder allgemeiner, wenn Sie mehr Methoden für Observables haben möchten.
WARNUNG: Dadurch werden alle über 50 Operatoren importiert und zu Ihrer Anwendung hinzugefügt, was sich auf Ihre Bundle-Größe und Ladezeiten auswirkt.

import 'rxjs/Rx';

Sehen dieses Problem für mehr Details.

  • Welche Fehler bleiben noch? Sie können einige spezifische Fragen dazu auf stackoverflow stellen 😉 Diese Frage könnte Ihnen vielleicht auch helfen: stackoverflow.com/questions/34450131/….

    – Thierry Templier

    10. Januar 2016 um 8:55 Uhr


  • Ab Angular 2 RC 0 ist dies nicht mehr erforderlich.

    – Onur Yıldırım

    30. Juli 2016 um 12:17 Uhr

  • @OnurYıldırım, mit rc.4 ist dieser Import immer noch erforderlich, es sei denn, ich mache etwas falsch.

    – Josef Gabriel

    3. August 2016 um 2:37 Uhr

  • Bitte verwenden Sie nicht ‘import ‘rxjs/Rx’;’ weil es alles importiert und rxjs ziemlich groß ist. Importieren Sie die Operatoren nach Bedarf einzeln.

    – Drag0

    22. September 2016 um 13:56 Uhr

  • Angular 2 mit rxjs: 5.0.0-beta.12 hier. Und das musste ich noch import 'rxjs/add/operator/do'… Während wir das nicht tun müssen .map() mehr. Aber das hat mir geholfen .do() Fall, um zu erkennen, dass ich es speziell importieren muss. Vielen Dank! Eine Stimme von mir 🙂

    – Herr Croft

    25. September 2016 um 17:56 Uhr


Benutzeravatar von Mark Rajcok
Markus Rajcok

Nur ein paar Hintergrundinformationen… Die neu geprägten Serverkommunikation dev guide (endlich) diskutiert/erwähnt/erklärt dies:

Die RxJS-Bibliothek ist ziemlich groß. Größe spielt eine Rolle, wenn wir eine Produktionsanwendung erstellen und sie auf Mobilgeräten bereitstellen. Wir sollten nur die Features einbauen, die wir wirklich brauchen.

Dementsprechend stellt Angular eine abgespeckte Version von bereit Observable in dem rxjs/Observable Modul, eine Version, der fast alle Operatoren fehlen, einschließlich derjenigen, die wir hier verwenden möchten, wie z map Methode.

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

Wie @Thierry bereits geantwortet hat, können wir einfach die benötigten Operatoren einfügen:

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 den gesamten Satz von Operatoren verwenden. WARNUNG: Dadurch werden alle über 50 Operatoren zu Ihrem App-Bundle hinzugefügt, was sich auf die Ladezeiten auswirkt

import 'rxjs/Rx';

  • importiere ‘rxjs/Rx’; Beeindruckend. und mein ganzes Haarziehen verschwindet sofort. Ich kann nicht glauben, dass dies nicht auf der ganzen Welt für Rxjs/Angular2 gedruckt wird. Danke!!!

    – JimB

    23. März 2016 um 16:59 Uhr

  • Aber es wird häufig nicht fusseln, standardmäßig ist es ein Import auf der schwarzen Liste. Erstellen Sie ein neues Winkel-CLI-Projekt, Sie werden sehen. Ich liebe die Bequemlichkeit selbst, aber die Konvention an den Orten, an denen ich in NYC arbeite, ist es nicht, es zu tun.

    – Tim Consolazio

    20. April 2018 um 13:54 Uhr


Benutzeravatar von Sachila Ranawaka
Sachila Ranawaka

Aus rxjs 5.5 ab können Sie die verwenden verrohrbar Betreiber

import { map } from 'rxjs/operators';

Was ist falsch an der import 'rxjs/add/operator/map';

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

Wenn Sie sich später entscheiden, sie zu entfernen map -Operator aus dem Code, der den beobachtbaren Stream verarbeitet, aber die entsprechende import-Anweisung, den Code, der implementiert, nicht entfernen map bleibt ein Teil der Observable.prototype.

Wenn die Bundler versuchen, den unbenutzten Code (auch bekannt tree shaking), können sie sich entscheiden, den Code des zu behalten map Operator im Observable, obwohl er nicht in der Anwendung verwendet wird.

LösungPipeable operators

Verrohrbar Operatoren sind reine Funktionen und patchen die nicht Beobachtbar. Sie können Operatoren mithilfe der ES6-Importsyntax importieren import { map } from "rxjs/operators" und packen sie dann in eine Funktion pipe() das nimmt eine variable Anzahl von Parametern, dh verkettbare Operatoren.

Etwas wie das:

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

  • Ja, jetzt mit Rxjs-Version 7+ wird empfohlen, Pipeable-Operatoren mit Pipe zu verwenden, schön, ich fand alle vorherigen Antworten alt und nicht mit den aktuellen Versionen von Angular und Rxjs aktualisiert

    – Rebai Ahmed

    13. Juli 2021 um 23:03 Uhr

Mit Angular 5 wurde der RxJS-Import verbessert.

Anstatt von

import 'rxjs/add/operator/map';

Wir können jetzt

import { map } from 'rxjs/operators';

Verwenden Observable.subscribe sollte direkt 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()); // <<--
    }
}

  • Dies ist kein sehr effizienter Ansatz. Wenn es beispielsweise mehrere Abonnenten gibt, muss jeder die Karte auf den Daten ausführen, anstatt dies nur einmal im Dienst zu tun. Ich denke, OP hatte den richtigen Ansatz, hatte nur nicht das richtige Modul geladen, um es zu verwenden.

    – Evan Scholle

    25. Januar 2016 um 18:17 Uhr

Benutzeravatar von Jitendra Ahuja
Jitendra Ahuja

Für Angular-Versionen 5 und höher sieht die aktualisierte Importzeile wie folgt aus:

import { map } from 'rxjs/operators';

ODER

import { map } from 'rxjs/operators';

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

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

import 'rxjs/add/operator/map';

ODER

import 'rxjs/add/operators/map';

Wenn Sie immer noch auf ein Problem stoßen, müssen Sie mit gehen:

import 'rxjs/Rx';

Ich möchte nicht, dass Sie es direkt verwenden, weil es die Ladezeit erhöht, da es eine große Anzahl von Operatoren enthält (nützliche und unnütze), was nach den Industrienormen keine gute Praxis ist, also stellen Sie sicher Sie versuchen zuerst, die oben genannten Importzeilen zu verwenden, und wenn das nicht funktioniert, sollten Sie sich für rxjs/Rx entscheiden

  • Dies ist kein sehr effizienter Ansatz. Wenn es beispielsweise mehrere Abonnenten gibt, muss jeder die Karte auf den Daten ausführen, anstatt dies nur einmal im Dienst zu tun. Ich denke, OP hatte den richtigen Ansatz, hatte nur nicht das richtige Modul geladen, um es zu verwenden.

    – Evan Scholle

    25. Januar 2016 um 18:17 Uhr

Benutzeravatar von Stephen Rauch
Stephan Rauch

Ich habe eine Lösung für dieses Problem

Installieren Sie dieses Paket:

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

importieren Sie dann diese Bibliothek

import 'rxjs/add/operator/map'

Starten Sie dann endlich Ihr ionisches Projekt neu

ionic serve -l

1436660cookie-checkAngular HTTP GET mit TypeScript-Fehler http.get(…).map ist keine Funktion in [null]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy