HTTP GET angular con error de TypeScript http.get(…).map no es una función en [null]

8 minutos de lectura

Avatar de usuario de Claudiu Matei
claudio matei

Tengo un problema con HTTP en Angular.

Solo quiero GET a JSON lista y mostrarlo en la vista.

clase de servicio

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

Y en el HallListComponent llamo al getHalls método del servicio:

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

Sin embargo, tengo una excepción:

TypeError: this.http.get(…).map no es una función en [null]

pasillo-centro.componente

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{}

aplicación.componente

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"
  ]
}

  • ¿No devuelve http.get una promesa?

    – bmm6o

    29 de diciembre de 2015 a las 16:38

  • @bmm6o Lo nuevo Http el servicio devuelve un observable

    – Broco

    29 de diciembre de 2015 a las 16:39

  • Me encontré con un problema casi idéntico al intentar migrar un proyecto de Angular2 beta-17 a la versión final. Sin embargo, el problema para mí era mi IDE, usando VS 2015, Actualización 3. La extensión del servicio de lenguaje TypeScript todavía estaba en 1.8.36mientras que la guía de inicio rápido de ng2 (mientras escribo esto) está usando "typescript": "^2.0.2". Actualización del idioma TS. el servicio a través de Extensiones y Actualizaciones funcionó para mí. Mientras se instalaba esa actualización, encontré esta respuesta SO, que termina con la misma conclusión.

    – Eric Arrendamiento

    21 de septiembre de 2016 a las 7:03

  • Para phpstorm/webstorm, actualizar la versión mecanografiada con la biblioteca de mi proyecto también resolvió el problema. Seguí los pasos de esta respuesta SO: stackoverflow.com/a/31608934/1291428

    – Sebas

    11 dic 2016 a las 15:20


Avatar de usuario de Thierry Templier
Thierry Templier

Creo que necesitas importar esto:

import 'rxjs/add/operator/map'

O, de manera más general, esto si desea tener más métodos para observables.
ADVERTENCIA: Esto importará los más de 50 operadores y los agregará a su aplicación, lo que afectará el tamaño del paquete y los tiempos de carga.

import 'rxjs/Rx';

Ver este problema para más detalles.

  • ¿Qué errores aún quedan? Puede hacer algunas preguntas específicas sobre esto en stackoverflow 😉 Esta pregunta quizás también podría ayudarlo: stackoverflow.com/questions/34450131/….

    – Thierry Templier

    10 de enero de 2016 a las 8:55


  • A partir de Angular 2 RC 0, esto ya no es necesario.

    – Onur Yıldırım

    30 de julio de 2016 a las 12:17

  • @OnurYıldırım, usando rc.4, aún se requiere esta importación, a menos que esté haciendo algo mal.

    – José Gabriel

    3 de agosto de 2016 a las 2:37

  • No use ‘importar ‘rxjs/Rx’;’ porque importa todo y rxjs tiende a ser bastante grande. Importe operadores uno por uno a medida que los necesite.

    – Arrastrar0

    22/09/2016 a las 13:56

  • Angular 2 con rxjs: 5.0.0-beta.12 aquí. Y todavía tenía que import 'rxjs/add/operator/do'… Si bien no tenemos que hacer esto para .map() más. Pero esto ayudó a mi .do() caso, para darme cuenta de que específicamente necesito importarlo. ¡Gracias! Un voto de mi parte 🙂

    – Sr. Croft

    25/09/2016 a las 17:56


Avatar de usuario de Mark Rajcok
Marcos Rajcok

Solo algunos antecedentes… Los recién acuñados Comunicación del servidor la guía de desarrollo (finalmente) discute/menciona/explica esto:

La biblioteca RxJS es bastante grande. El tamaño importa cuando construimos una aplicación de producción y la implementamos en dispositivos móviles. Deberíamos incluir solo aquellas características que realmente necesitamos.

En consecuencia, Angular expone una versión simplificada de Observable en el rxjs/Observable module, una versión que carece de casi todos los operadores, incluidos los que nos gustaría usar aquí, como el map método.

Depende de nosotros agregar los operadores que necesitamos. Podríamos agregar cada operador, uno por uno, hasta que tuviéramos una implementación observable personalizada ajustada con precisión a nuestros requisitos.

Entonces, como @Thierry ya respondió, podemos simplemente obtener los operadores que necesitamos:

import 'rxjs/add/operator/map';
import 'rxjs/operator/delay';
import 'rxjs/operator/mergeMap';
import 'rxjs/operator/switchMap';

O, si somos perezosos, podemos extraer el conjunto completo de operadores. ADVERTENCIA: esto agregará los más de 50 operadores a su paquete de aplicaciones y afectará los tiempos de carga

import 'rxjs/Rx';

  • importar ‘rxjs/Rx’; guau. y todos mis tirones de cabello desaparecen instantáneamente. No puedo creer que esto no esté impreso en todo el mundo para Rxjs/Angular2. ¡¡¡Gracias!!!

    – JimB

    23 de marzo de 2016 a las 16:59

  • Pero con frecuencia no genera pelusa, por defecto es una importación en la lista negra. Cree un nuevo proyecto CLI angular, verá. Me encanta la conveniencia, pero la convención en los lugares donde trabajo en Nueva York es no hacerlo.

    – Tim Consolacio

    20 de abril de 2018 a las 13:54


Avatar de usuario de Sachila Ranawaka
Sachila Ranawaka

De rxjs 5.5 en adelante, puede utilizar el canalizable operadores

import { map } from 'rxjs/operators';

¿Qué tiene de malo el import 'rxjs/add/operator/map';

Cuando usamos este enfoque map el operador será parcheado para observable.prototype y se convierte en parte de este objeto.

Si más adelante decide eliminar map operador del código que maneja el flujo observable pero no elimina la declaración de importación correspondiente, el código que implementa map sigue siendo parte del Observable.prototype.

Cuando los empaquetadores intentan eliminar el código no utilizado (alias tree shaking), pueden decidir conservar el código de la map operador en el Observable aunque no se esté utilizando en la aplicación.

SoluciónPipeable operators

canalizable Los operadores son funciones puras y no parchean el Observable. Puede importar operadores utilizando la sintaxis de importación de ES6 import { map } from "rxjs/operators" y luego envolverlos en una función pipe() que toma un número variable de parámetros, es decir, operadores encadenables.

Algo como esto:

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

  • Sí, actualmente con la versión 7+ de Rxjs, se recomienda usar operadores pipeables usando pipe, bueno, encontré todas las respuestas anteriores antiguas y no actualizadas con las versiones actuales de Angular y Rxjs

    – Rebai Ahmed

    13 de julio de 2021 a las 23:03

Con Angular 5 se mejora la importación de RxJS.

En vez de

import 'rxjs/add/operator/map';

ahora podemos

import { map } from 'rxjs/operators';

Usando Observable.subscribe directamente debería funcionar.

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

  • Este no es un enfoque muy eficiente. Por ejemplo, si hay varios suscriptores, cada uno tendrá que ejecutar el mapa en los datos, en lugar de hacerlo solo una vez en el servicio. Creo que OP tuvo el enfoque correcto, simplemente no tenía cargado el módulo correcto para usarlo.

    – Evan solla

    25 de enero de 2016 a las 18:17

Avatar de usuario de Jitendra Ahuja
Jitendra Ahuja

Para las versiones Angular 5 y superiores, la línea de importación actualizada se ve así:

import { map } from 'rxjs/operators';

O

import { map } from 'rxjs/operators';

Además, estas versiones son totalmente compatibles con los operadores Pipable, por lo que puede usar fácilmente .pipe() y .subscribe().

Si está utilizando la versión 2 de Angular, la siguiente línea debería funcionar absolutamente bien:

import 'rxjs/add/operator/map';

O

import 'rxjs/add/operators/map';

Si aún encuentra un problema, entonces debe ir con:

import 'rxjs/Rx';

No preferiría que lo use directamente porque aumenta el tiempo de carga, ya que tiene una gran cantidad de operadores (útiles y no útiles), lo cual no es una buena práctica de acuerdo con las normas de la industria, así que asegúrese primero intenta usar las líneas de importación mencionadas anteriormente, y si eso no funciona, entonces debe optar por rxjs/Rx

  • Este no es un enfoque muy eficiente. Por ejemplo, si hay varios suscriptores, cada uno tendrá que ejecutar el mapa en los datos, en lugar de hacerlo solo una vez en el servicio. Creo que OP tuvo el enfoque correcto, simplemente no tenía cargado el módulo correcto para usarlo.

    – Evan solla

    25 de enero de 2016 a las 18:17

Avatar de usuario de Stephen Rauch
Esteban Rauch

tengo una solucion a este problema

Instale este paquete:

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

luego importa esta biblioteca

import 'rxjs/add/operator/map'

finalmente reinicie su proyecto iónico entonces

ionic serve -l

¿Ha sido útil esta solución?