Ich habe ein Problem mit HTTP in Angular.
Ich möchte nur GET
eine JSON
Liste auflisten und in der Ansicht anzeigen.
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]
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{}
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 { }
{
"compilerOptions": {
"target": "ES5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules"
]
}
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.
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
imrxjs/Observable
-Modul verfügbar, einer Version, der fast alle Operatoren fehlen, einschließlich derjenigen, die wir hier verwenden möchten, wie beispielsweise diemap
-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';
Mit Angular 5 wird der RxJS-Import verbessert.
Anstatt
import 'rxjs/add/operator/map';
Wir können jetzt
import { map } from 'rxjs/operators';
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())
);
}
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()); // <<--
}
}
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!
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
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
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';
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
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';
Angular 6 - nur Import 'rxjs/Rx' hat den Trick für mich gemacht
Der globale Import ist sicher.
importiere 'rxjs/Rx';
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
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.
import 'rxjs/add/operator/map';
wird dein Problem lösen
Ich habe es in Winkel 5.2.0 und Rxjs 5.5.2 getestet
Ich habe die folgenden Befehle ausprobiert und es wurde behoben:
npm install [email protected] [email protected] --save
import 'rxjs/Rx';