Angular HTTP GET avec l’erreur TypeScript http.get (…) .map n’est pas une fonction dans

J’ai un problème avec HTTP dans Angular.

Je veux juste obtenir une liste JSON et l’afficher dans la vue.

Classe de service

 import {Injectable} from "angular2/core"; import {Hall} from "./hall"; import {Http} from "angular2/http"; @Injectable() export class HallService { public http:Http; public static PATH:ssortingng = 'app/backend/' constructor(http:Http) { this.http=http; } getHalls() { return this.http.get(HallService.PATH + 'hall.json').map((res:Response) => res.json()); } } 

Et dans le HallListComponent j’appelle la méthode getHalls 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]

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:` 

my app

`, 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: ` 

Examenopdracht Factory

Hall overview `, directives: [ROUTER_DIRECTIVES] }) @RouteConfig([ {path: '/hall-center/...', name:'HallCenter',component:HallCenterComponent,useAsDefault:true} ]) export class AppComponent { }

tsconfig.json

 { "comstackrOptions": { "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 si vous voulez avoir plus de méthodes pour les observables. AVERTISSEMENT: Ceci importera tous les opérateurs 50+ et les appenda à votre application, affectant ainsi la taille de votre bundle et les temps de chargement.

 import 'rxjs/Rx'; 

Voir ce numéro pour plus de détails.

Juste un peu de contexte … Le guide de développement de Server Communication nouvellement créé (enfin) discute / mentionne / explique ceci:

La bibliothèque RxJS est assez grande. La taille est importante lorsque nous créons une application de production et que nous 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 simplifiée de Observable dans le module rxjs/Observable , une version qui manque de presque tous les opérateurs, y compris ceux que nous aimerions utiliser ici, comme la méthode des map .

A nous d’append les opérateurs dont nous avons besoin. Nous pourrions append chaque opérateur, un par un, jusqu’à ce que nous ayons une implémentation Observable personnalisée parfaitement adaptée à nos besoins.

Comme @Thierry a déjà répondu, nous pouvons simplement récupérer 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 sums paresseux, nous pouvons tirer parti de l’ensemble des opérateurs. AVERTISSEMENT: cela va append tous les 50 opérateurs à votre application 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'; 

Utiliser Observable.subscribe directement devrait fonctionner.

 @Injectable() export class HallService { public http:Http; public static PATH:ssortingng = '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()); // <<-- } } 

A partir de rxjs 5.5 , vous pouvez utiliser les opérateurs

 import { map } from 'rxjs/operators'; 

Qu’est-ce qui ne va pas avec l’ import 'rxjs/add/operator/map';

Lorsque nous utilisons cette approche map opérateur sera assigné à observable.prototype et deviendra une partie de cet object.

Si, plus tard, vous décidez de supprimer l’opérateur de map du code qui gère le stream observable mais que vous ne parvenez pas à supprimer l’instruction d’importation correspondante, le code qui implémente map rest une partie de Observable.prototype .

Lorsque le bundler essaie d’éliminer le code inutilisé ( aka tree shaking ), il peut décider de conserver le code de l’opérateur de map dans l’observable, même s’il n’est pas utilisé dans l’application.

SolutionPipeable operators

Les opérateurs canalisables sont des fonctions pures et ne corrigent pas l’ Observable . Vous pouvez importer des opérateurs utilisant la syntaxe d’ import { map } from "rxjs/operators" ES6 import import { map } from "rxjs/operators" , puis les envelopper dans une fonction pipe() qui prend un nombre variable de parameters, à savoir des opérateurs chaînables.

Quelque chose comme ça:

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

Pour les versions angulars 5 et supérieures, la ligne d’importation mise à jour ressemble à:

 import { map } from 'rxjs/operators'; 

OU

 import { map } from 'rxjs/operators'; 

De plus, ces versions supportent totalement les opérateurs de pipettes, vous pouvez donc facilement utiliser .pipe () et .subscribe ().

Si vous utilisez la version angular 2, la ligne suivante devrait fonctionner parfaitement:

 import 'rxjs/add/operator/map'; 

OU

 import 'rxjs/add/operators/map'; 

Si vous rencontrez toujours un problème, vous devez aller avec:

 import 'rxjs/Rx'; 

Je ne préférerais pas que vous l’utilisiez directement bcoz il augmente le temps de chargement, car il y a un grand nombre d’opérateurs (utiles et inutiles) ce qui n’est pas une bonne pratique selon les normes de l’indussortinge, alors assurez-vous vous essayez d’utiliser les lignes d’importation mentionnées ci-dessus en premier, et si cela ne fonctionne pas, alors vous devriez aller pour rxjs / Rx

J’ai une solution à ce problème

Installez ce paquet:

 npm install rxjs@6 rxjs-compat@6 --save 

puis importez cette librairie

 import 'rxjs/add/operator/map' 

enfin redémarrer votre projet ionique alors

 ionic serve -l 

Comme le service HTTP dans angular2 renvoie un type Observable , à partir de votre répertoire d’installation Angular2 (‘node_modules’ dans mon cas), nous devons importer la fonction map de l’observable dans votre composant en utilisant le service http , comme:

 import 'rxjs/add/operator/map'; 

La carte que vous utilisez ici n’est pas le .map() en javascript, c’est la fonction de carte Rxjs qui fonctionne sur les Observables dans 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 Applique une fonction de projet donnée à chaque valeur émise par la source Observable et émet les valeurs résultantes sous forme d’observable.

Il suffit donc de l’importer comme ceci:

 import 'rxjs/add/operator/map'; 

Vrai, RxJs a séparé son opérateur de carte dans un module séparé et vous devez maintenant l’importer de manière explicite comme tout autre opérateur.

import rxjs/add/operator/map;

et vous irez bien.

L’importation globale est sans danger.

importer ‘rxjs / Rx’;

 import 'rxjs/add/operator/map'; 

va résoudre votre problème

Je l’ai testé en angular 5.2.0 et rxjs 5.5.2

Angular 6 – importation seule ‘rxjs / Rx’ a fait l’affaire pour moi

Ajoutez simplement la ligne dans votre fichier,

importer ‘rxjs / Rx’;

Il importera des tas de dépendances. Testé en angular 5

Cela se produit parce que vous utilisez les fonctions RXJS et RXJS ne sont pas statiques, 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 depuis la bibliothèque RXJS.

Mais si vous utilisez rxjs-compat, il vous suffit d’importer les opérateurs rxjs-compat