J'ai un problème avec HTTP en angulaire.
Je veux juste GET
une liste JSON
et l'afficher dans la vue.
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());
}
}
Et dans la HallListComponent
, j'appelle la méthode getHalls
à partir du 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;
});
}
}
Cependant, j'ai une exception:
TypeError: this.http.get (...). Map n'est pas une fonction dans [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"
]
}
Je pense que vous devez importer ceci:
import 'rxjs/add/operator/map'
Ou plus généralement ceci si vous voulez avoir plus de méthodes pour les observables .AVERTISSEMENT: Ceci importera plus de 50 opérateurs et les ajoutera à votre application, affectant ainsi la taille de votre paquet et les temps de chargement.
import 'rxjs/Rx';
Voir ce numéro pour plus de détails.
Juste un peu de contexte ... Le/Mentionné Serveur Communication Guide dev (enfin) discute/mentionne/explique:
La bibliothèque RxJS est assez grande. La taille compte lorsque nous construisons une application de production et la déployons sur des appareils mobiles. Nous devrions inclure uniquement les fonctionnalités dont nous avons réellement besoin.
En conséquence, Angular expose une version réduite de
Observable
dans le modulerxjs/Observable
, une version qui manque de presque tous les opérateurs, y compris ceux que nous aimerions utiliser ici, tels que la méthodemap
.C'est à nous d'ajouter les opérateurs dont nous avons besoin. Nous pourrions ajouter chaque opérateur, un par un, jusqu'à ce que nous ayons une implémentation Observable personnalisée parfaitement adaptée à nos besoins.
Donc, comme @Thierry a déjà répondu, nous pouvons simplement attirer les opérateurs dont nous avons besoin:
import 'rxjs/add/operator/map';
import 'rxjs/operator/delay';
import 'rxjs/operator/mergeMap';
import 'rxjs/operator/switchMap';
Ou, si nous sommes paresseux, nous pouvons intégrer l'ensemble des opérateurs. ATTENTION: ceci ajoutera les 50 opérateurs et plus à votre bundle d'applications et affectera les temps de chargement
import 'rxjs/Rx';
Avec Angular 5, l’importation RxJS est améliorée.
Au lieu de
import 'rxjs/add/operator/map';
Nous pouvons maintenant
import { map } from 'rxjs/operators';
À partir de rxjs 5.5, vous pouvez utiliser les opérateurs pipeable
import { map } from 'rxjs/operators';
Quel est le problème avec le import 'rxjs/add/operator/map';
Lorsque nous utilisons cette approche, l'opérateur map
sera corrigé à observable.prototype
et fera partie de cet objet.
Si par la suite, vous décidez de supprimer l'opérateur map
du code qui gère le flux observable mais ne supprimez pas l'instruction d'importation correspondante, le code qui implémente map
fait toujours partie du Observable.prototype
.
Lorsque les groupeurs essaient d’éliminer le code inutilisé (a.k.a.tree shaking
), ils peuvent décider de conserver le code de l’opérateur map
dans l’Observable même s’il n’est pas utilisé dans l’application.
Solution - Pipeable operators
Les opérateurs Pipeable sont des fonctions pures et ne corrigent pas le Observable. Vous pouvez importer des opérateurs à l'aide de la syntaxe d'importation ES6 import { map } from "rxjs/operators"
, puis les envelopper dans une fonction pipe()
prenant un nombre variable de paramètres, c'est-à-dire des opérateurs pouvant être chaînés.
Quelque chose comme ça:
getHalls() {
return this.http.get(HallService.PATH + 'hall.json')
.pipe(
map((res: Response) => res.json())
);
}
Utiliser Observable.subscribe
directement devrait fonctionner.
@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()); // <<--
}
}
Version angulaire 6 "0.6.8" Rxjs version 6 "^ 6.0.0"
cette solution est pour:
"@angular-devkit/core": "0.6.8",
"rxjs": "^6.0.0"
comme nous le savons tous, angular se développe tous les jours, il y a donc beaucoup de changements tous les jours. Cette solution concerne les angular 6 et rxjs 6
premier à travailler avec http yo devrait l’importer de: après tout, vous devez déclarer le HttpModule dans app.module.ts
import { Http } from '@angular/http';
et vous devez ajouter HttpModule à Ngmodule -> imports
imports: [
HttpModule,
BrowserModule,
FormsModule,
RouterModule.forRoot(appRoutes)
],
deuxième à travailler avec la carte, vous devez d’abord importer le tuyau:
import { pipe } from 'rxjs';
troisièmement, vous devez importer la fonction de carte depuis:
import { map } from 'rxjs/operators';
vous devez utiliser map inside pipe comme dans cet exemple:
constructor(public http:Http){ }
getusersGET(){
return this.http.get('http://jsonplaceholder.typicode.com/users').pipe(
map(res => res.json() ) );
}
ça marche parfaitement bonne chance!
J'ai une solution à ce problème
Installez ce paquet:
npm install rxjs@6 rxjs-compat@6 --save
puis importer cette bibliothèque
import 'rxjs/add/operator/map'
enfin redémarrer votre projet ionique puis
ionic serve -l
Pour les versions angulaires 5 et supérieures, la ligne d'importation mise à jour se présente comme suit:
import { map } from 'rxjs/operators';
OU
import { map } from 'rxjs/operators';
De plus, ces versions supportent totalement les opérateurs Pipable, vous pouvez donc utiliser facilement .pipe () et .subscribe ().
Si vous utilisez la version 2 angulaire, la ligne suivante devrait fonctionner parfaitement:
import 'rxjs/add/operator/map';
OU
import 'rxjs/add/operators/map';
Si vous rencontrez toujours un problème, alors vous devez utiliser:
import 'rxjs/Rx';
Je ne préférerai pas que vous l'utilisiez directement, car cela augmente le temps de chargement, car il contient un grand nombre d'opérateurs (utiles et non utiles), ce qui n'est pas une bonne pratique selon les normes de l'industrie. vous essayez d’utiliser d’abord les lignes d’importation mentionnées ci-dessus, et si cela ne fonctionne pas, vous devriez alors choisir rxjs/Rx
La map que vous utilisez ici, n’est pas la .map()
en javascript, c’est la fonction de la carte Rxjs qui fonctionne sur Observables
en Angular ...
Donc, dans ce cas, vous devez l'importer si vous souhaitez utiliser la carte sur les données de résultat ...
map(project: function(value: T, index: number): R, thisArg: any): Observable<R>
Applique une fonction de projet donnée à chaque valeur émise par la source Observable et émet les valeurs résultantes en tant que Observable.
Alors importez-le simplement comme ceci:
import 'rxjs/add/operator/map';
Ajoutez simplement la ligne dans votre fichier,
importer 'rxjs/Rx';
Il importera un tas de dépendances. Testé en angulaire 5
Puisque Http service dans angular2 renvoie un Observable type, À partir de votre répertoire d’installation Angular2 ("node_modules" dans mon cas), nous devons importer la fonction de mappage de l’observable composant using http service, en tant que:
import 'rxjs/add/operator/map';
Angular 6 - seule l'importation 'rxjs/Rx' a fait l'affaire
L'importation globale est sans danger.
importer 'rxjs/Rx';
cela se produit parce que vous utilisez la fonction rxjs et que la fonction rxjs n'est pas statique, ce qui signifie que vous ne pouvez pas les appeler directement. Vous devez appeler les méthodes à l'intérieur du canal et importer cette fonction à partir de la bibliothèque rxjs.
Mais si vous utilisez rxjs-compat, il vous suffit d'importer les opérateurs rxjs-compat
Certes, RxJs a séparé son opérateur cartographique dans un module séparé et vous devez maintenant l’importer explicitement comme tout autre opérateur.
import rxjs/add/operator/map;
et tout ira bien.
import 'rxjs/add/operator/map';
va résoudre votre problème
Je l'ai testé dans les versions 5.2.0 et 5.5.2 angulaires
J'ai essayé ci-dessous des commandes et cela se corrige:
npm install rxjs@6 rxjs-compat@6 --save
import 'rxjs/Rx';