from - HTTP GET angular con error de TypeScript http.get(...).map no es una función en
subscribe angular 6 (17)
Tengo un problema con HTTP en Angular.
Solo quiero
GET
una lista
JSON
y mostrarla 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 método
getHalls
desde el 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, obtuve una excepción:
TypeError: this.http.get (...). Map no es una función en [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"
]
}
A partir de rxjs 5.5 en adelante, puede usar los operadores canalizables
import { map } from ''rxjs/operators'';
Lo que está mal con la
import ''rxjs/add/operator/map'';
Cuando usamos este enfoque, el operador del
map
será parcheado a
observable.prototype
y se convertirá en parte de este objeto.
Si más adelante decide eliminar el operador de
map
del código que maneja la secuencia observable pero no elimina la declaración de importación correspondiente, el código que implementa el
map
sigue siendo parte del
Observable.prototype
.
Cuando los agrupadores intentan eliminar el código no utilizado (
también conocido como
tree shaking
), pueden decidir mantener el código del operador del
map
en el Observable aunque no se esté utilizando en la aplicación.
Solución
:
Pipeable operators
Los
operadores
canalizables
son funciones puras y no parchean el
Observable
.
Puede importar operadores utilizando la sintaxis de
import { map } from "rxjs/operators"
ES6 import
import { map } from "rxjs/operators"
y luego envolverlos en una
pipe()
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())
);
}
Angular 6: solo importar ''rxjs / Rx'' fue el truco para mí
Con Angular 5 se mejora la importación de RxJS.
En lugar de
import ''rxjs/add/operator/map'';
Ahora podemos
import { map } from ''rxjs/operators'';
Creo que necesitas importar esto:
import ''rxjs/add/operator/map''
O más generalmente 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 de su paquete y los tiempos de carga.
import ''rxjs/Rx'';
Vea este número para más detalles.
Dado que el servicio Http en angular2 devuelve un tipo Observable , desde su directorio de instalación Angular2 (''node_modules'' en mi caso), necesitamos importar la función de mapa del Observable en su componente usando el servicio http , como:
import ''rxjs/add/operator/map'';
El
mapa
que usa aquí, no es el
.map()
en javascript, es la función de mapa Rxjs que trabaja en
Observables
en Angular ...
Entonces, en ese caso, debe importarlo si desea usar el mapa en los datos de resultados ...
map(project: function(value: T, index: number): R, thisArg: any): Observable<R>
Aplica una función de proyecto determinada a cada valor emitido por el Observable de origen y emite los valores resultantes como un Observable.
Así que simplemente impórtalo así:
import ''rxjs/add/operator/map'';
Es cierto que RxJs ha separado su operador de mapa en un módulo separado y ahora necesita importarlo explícitamente como cualquier otro operador.
import rxjs/add/operator/map;
y estarás bien
Intenté los siguientes comandos y se solucionó:
npm install rxjs@6 rxjs-compat@6 --save
import ''rxjs/Rx'';
La importación global es segura.
importar ''rxjs / Rx'';
Para las versiones angulares 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 de Pipable para que pueda usar fácilmente .pipe () y .subscribe ().
Si está utilizando Angular versión 2, entonces 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, debe ir con:
import ''rxjs/Rx'';
No preferiré que lo use directamente porque aumenta el tiempo de carga, ya que tiene una gran cantidad de operadores (útiles y no útiles), lo que no es una buena práctica de acuerdo con las normas de la industria, así que asegúrese de intente usar primero las líneas de importación mencionadas anteriormente, y si eso no funciona, entonces debería usar rxjs / Rx
Simplemente agregue la línea en su archivo,
importar ''rxjs / Rx'';
Importará muchas dependencias. Probado en angular 5
Solo algunos antecedentes ... La nueva guía de desarrollo de Server Communication (finalmente) discute / menciona / explica esto:
La biblioteca RxJS es bastante grande. El tamaño importa cuando creamos 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 reducida de
Observable
en el módulorxjs/Observable
, una versión que carece de casi todos los operadores, incluidos los que nos gustaría usar aquí, como el método demap
.Depende de nosotros agregar los operadores que necesitamos. Podríamos agregar cada operador, uno por uno, hasta que tengamos una implementación Observable personalizada ajustada con precisión a nuestros requisitos.
Entonces, como @Thierry ya respondió, podemos atraer a los operadores que necesitamos:
import ''rxjs/add/operator/map'';
import ''rxjs/operator/delay'';
import ''rxjs/operator/mergeMap'';
import ''rxjs/operator/switchMap'';
O, si somos flojos, podemos atraer al 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'';
Tengo una solución a este problema.
Instala este paquete:
npm install rxjs@6 rxjs-compat@6 --save
luego importe esta biblioteca
import ''rxjs/add/operator/map''
finalmente reinicie su proyecto iónico y luego
ionic serve -l
Usar
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()); // <<--
}
}
Versión angular 6 "0.6.8" rxjs versión 6 "^ 6.0.0"
Esta solución es para:
"@angular-devkit/core": "0.6.8",
"rxjs": "^6.0.0"
como todos sabemos, angular se está desarrollando todos los días, por lo que hay muchos cambios todos los días y esta solución es para angular 6 y rxjs 6
primero para trabajar con http, debería importarlo desde: después de todo, debe declarar el HttpModule en app.module.ts
import { Http } from ''@angular/http'';
y tienes que agregar HttpModule a Ngmodule -> importaciones
imports: [
HttpModule,
BrowserModule,
FormsModule,
RouterModule.forRoot(appRoutes)
],
segundo para trabajar con el mapa, primero debe importar la tubería:
import { pipe } from ''rxjs'';
tercero, necesita importar la función de mapa desde:
import { map } from ''rxjs/operators'';
tienes que usar map inside pipe como este ejemplo:
constructor(public http:Http){ }
getusersGET(){
return this.http.get(''http://jsonplaceholder.typicode.com/users'').pipe(
map(res => res.json() ) );
}
eso funciona perfectamente buena suerte!
esto está sucediendo porque está utilizando los rxjs y en la función rxjs no son estáticos, lo que significa que no puede llamarlos directamente, debe llamar a los métodos dentro de la tubería e importar esa función desde la biblioteca rxjs
Pero si está utilizando rxjs-compat, entonces solo necesita importar los operadores rxjs-compat
import ''rxjs/add/operator/map'';
resolverá tu problema
Lo probé en angular 5.2.0 y rxjs 5.5.2