web-dev-qa-db-fra.com

HTTP GET angulaire avec l'erreur TypeScript http.get (...). Map n'est pas une fonction dans [null]

J'ai un problème avec HTTP en angulaire. 

Je veux juste GET 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: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]

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

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.

514
Thierry Templier

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 module rxjs/Observable, une version qui manque de presque tous les opérateurs, y compris ceux que nous aimerions utiliser ici, tels que la méthode map.

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';
79
Mark Rajcok

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';
15
Claudiu

À 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())
    );
}
11
Sachila Ranawaka

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

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! 

4
nadir hamidou

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
3
divyajeet singh

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

3
Jitendra Ahuja

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';
2
Alireza

Ajoutez simplement la ligne dans votre fichier,

importer 'rxjs/Rx';

Il importera un tas de dépendances. Testé en angulaire 5

2
Mandeep Singh

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';
1
Amardeep Kohli

Angular 6 - seule l'importation 'rxjs/Rx' a fait l'affaire

1
Shimi Avizmil

L'importation globale est sans danger.

importer 'rxjs/Rx';

1
rut shah

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

0
Gurvinder Guraya

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.

0
Piyush P
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

0
Mayank Bhardwaj

J'ai essayé ci-dessous des commandes et cela se corrige:

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


import 'rxjs/Rx';
0
Phan Hero