GET HTTP angular com erro TypeScript http.get (…) .map não é uma função em [null]

334

Estou com um problema com o HTTP no Angular.

Eu só quero GETuma JSONlista e mostrá-la na exibição.

Classe de serviço

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

E no HallListComponenteu chamo o getHallsmétodo do serviço:

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

No entanto, recebi uma exceção:

TypeError: this.http.get (...). Map não é uma função em [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"
  ]
}
Claudiu
fonte
O http.get não retorna uma promessa?
bmm6o
11
@ bmm6o Os novos Httpretornos de serviços um observável
Brocco
11
Corri para um problema quase idêntico, tentando migrar um projeto do Angular2 beta-17 para a versão final. O problema para mim foi o meu IDE, porém, usando o VS 2015, atualização 3. A extensão do serviço de linguagem TypeScript ainda estava em 1.8.36, enquanto o guia de início rápido do ng2 (enquanto escrevo isso) está em uso "typescript": "^2.0.2". Atualizando o TS lang. serviço via Extensões e Atualizações fez o truque para mim. Enquanto essa atualização estava sendo instalada, me deparei com essa resposta do SO , que termina com a mesma conclusão.
Eric Lease
Para phpstorm / webstorm, atualizar a versão datilografada com a biblioteca do meu projeto também resolveu o problema. Eu segui os passos de esta resposta SO: stackoverflow.com/a/31608934/1291428
Sebas

Respostas:

538

Eu acho que você precisa importar isso:

import 'rxjs/add/operator/map'

Ou, mais geralmente, se você quiser ter mais métodos para observáveis. AVISO: Isso importará todos os mais de 50 operadores e os adicionará ao seu aplicativo, afetando assim o tamanho do pacote e os tempos de carregamento.

import 'rxjs/Rx';

Veja esta edição para mais detalhes.

Thierry Templier
fonte
11
Quais erros ainda permanecem? Você pode fazer algumas perguntas específicas sobre isso no stackoverflow ;-) Essa pergunta talvez também possa ajudá-lo: stackoverflow.com/questions/34450131/… .
Thierry Templier
11
A partir do Angular 2 RC 0, isso não é mais necessário.
Onur Yıldırım
3
@ OnurYıldırım, usando rc.4, essa importação ainda é necessária, a menos que eu esteja fazendo algo errado.
Joseph Gabriel
18
Por favor, não use 'import' rxjs / Rx ';' porque importa tudo e o rxjs tende a ser bem grande. Importe operadores um por um, conforme necessário.
usar o seguinte comando
11
Angular 2 com rxjs: 5.0.0-beta.12 aqui. E eu ainda tinha que import 'rxjs/add/operator/do'... Enquanto não precisamos mais fazer isso .map(). Mas isso ajudou meu .do()caso, ao perceber que preciso especificamente importá-lo. Obrigado! Um voto-se de mim :)
MrCroft
82

Apenas alguns antecedentes ... O recém-cunhado Guia de Desenvolvimento de Comunicação do Servidor (finalmente) discute / menciona / explica isso:

A biblioteca RxJS é bastante grande. O tamanho é importante quando criamos um aplicativo de produção e o implantamos em dispositivos móveis. Devemos incluir apenas os recursos que realmente precisamos.

Dessa forma, o Angular expõe uma versão simplificada Observabledo rxjs/Observablemódulo, uma versão que carece de quase todos os operadores, incluindo aqueles que gostaríamos de usar aqui, como o mapmétodo

Cabe a nós adicionar os operadores que precisamos. Poderíamos adicionar cada operador, um por um, até termos uma implementação observável personalizada ajustada precisamente aos nossos requisitos.

Portanto, como o @Thierry já respondeu, podemos apenas chamar os operadores de que precisamos:

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

Ou, se formos preguiçosos, podemos atrair todo o conjunto de operadores. AVISO: isso adicionará todos os mais de 50 operadores ao seu pacote de aplicativos e afetará o tempo de carregamento

import 'rxjs/Rx';
Mark Rajcok
fonte
2
importar 'rxjs / Rx'; Uau. e todo o meu cabelo puxando instantaneamente desaparece. Não acredito que isso não seja impresso em todo o mundo para Rxjs / Angular2. obrigado!!!
23416 JimB
Mas, com frequência, não é um problema, por padrão é uma importação na lista negra. Crie um novo projeto de CLI angular, você verá. Eu amo a conveniência, mas a convenção nos lugares em que trabalho em Nova York não é para fazê-lo.
Tim CONSOLAZIO
21

A partir do rxjs 5.5 , você pode usar os operadores canalizáveis

import { map } from 'rxjs/operators';

O que há de errado com o import 'rxjs/add/operator/map';

Quando usamos essa abordagem, o mapoperador será corrigido observable.prototype e se tornará parte desse objeto.

Se, posteriormente, você decidir remover o mapoperador do código que lida com o fluxo observável, mas falhar ao remover a instrução de importação correspondente, o código implementado mappermanecerá parte do Observable.prototype.

Quando os empacotadores tentam eliminar o código não utilizado ( aka tree shaking ), eles podem decidir manter o código do mapoperador no Observable, mesmo que ele não esteja sendo usado no aplicativo.

Solução -Pipeable operators

Operadores canalizáveis são funções puras e não corrigem o Observable . Você pode importar operadores usando a sintaxe de importação ES6 import { map } from "rxjs/operators"e envolvê-los em uma função pipe()que utiliza um número variável de parâmetros, ou seja, operadores encadeados.

Algo assim:

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

Com o Angular 5, a importação de RxJS é aprimorada.

Ao invés de

import 'rxjs/add/operator/map';

Agora podemos

import { map } from 'rxjs/operators';
Claudiu
fonte
Usando essa abordagem, agora na sua compilação incluirá apenas operadores usados ​​(neste caso, mapear), antes estava incluindo todos os operadores da biblioteca rxjs. verifique o link abaixo para obter mais detalhes. loiane.com/2017/08/angular-rxjs-imports
Hiren Shah
13

Usar Observable.subscribediretamente deve 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()); // <<--
    }
}
TheKojuEffect
fonte
5
Esta não é uma abordagem muito eficiente. Por exemplo, se houver vários assinantes, cada um terá que executar um mapa nos dados, em vez de apenas fazê-lo uma vez no serviço. Acho que o OP tinha a abordagem correta, mas não tinha o módulo certo carregado para usá-lo.
Evan Plaice
3

Para as versões 5 e superiores do Angular, a linha de importação atualizada é semelhante a:

import { map } from 'rxjs/operators';

OU

import { map } from 'rxjs/operators';

Além disso, essas versões são totalmente compatíveis com os operadores de tubulação, para que você possa usar facilmente .pipe () e .subscribe ().

Se você estiver usando o Angular versão 2, a seguinte linha deverá funcionar absolutamente bem:

import 'rxjs/add/operator/map';

OU

import 'rxjs/add/operators/map';

Se você ainda encontrar um problema, deverá:

import 'rxjs/Rx';

Não vou preferir que você o use diretamente, pois aumenta o tempo de carregamento, pois possui um grande número de operadores (úteis e não úteis), o que não é uma boa prática de acordo com as normas do setor, portanto, certifique-se de você tenta usar as linhas de importação acima mencionadas primeiro e, se isso não funcionar, você deve usar o rxjs / Rx

Jitendra Ahuja
fonte
3

Eu tenho uma solução para este problema

Instale este pacote:

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

então importe esta biblioteca

import 'rxjs/add/operator/map'

finalmente reinicie seu projeto iônico

ionic serve -l
divyajeet singh
fonte
3

Versão angular 6 "0.6.8" rxjs versão 6 "^ 6.0.0"

esta solução é para:

  "@angular-devkit/core": "0.6.8",
  "rxjs": "^6.0.0"

como todos sabemos que angular está sendo desenvolvido todos os dias, há muitas mudanças todos os dias e esta solução é para angular 6 e rxjs 6
trabalhar primeiro com o http. module.ts

import { Http } from '@angular/http';

e você precisa adicionar o HttpModule ao Ngmodule -> imports

  imports: [
    HttpModule,
    BrowserModule,
    FormsModule,
    RouterModule.forRoot(appRoutes)
  ],

segundo para trabalhar com o mapa, você deve primeiro importar o pipe:

import { pipe } from 'rxjs';

terceiro, você precisa da importação da função de mapa de:

import { map } from 'rxjs/operators';

você precisa usar o mapa dentro do pipe como este exemplo:

 constructor(public http:Http){  }

    getusersGET(){
        return this.http.get('http://jsonplaceholder.typicode.com/users').pipe(
         map(res => res.json()  )  );
    }

isso funciona perfeitamente boa sorte!

nadir hamidou
fonte
2

O mapa que você está usando aqui, não é o .map()javascript, é a função de mapa Rxjs que trabalha Observablesem Angular ...

Portanto, nesse caso, você precisará importá-lo se desejar usar o mapa nos dados do resultado ...

map(project: function(value: T, index: number): R, thisArg: any): Observable<R> Aplica uma determinada função de projeto a cada valor emitido pela fonte Observable e emite os valores resultantes como um Observable.

Então, basta importá-lo assim:

import 'rxjs/add/operator/map';
Alireza
fonte
1

Como o serviço Http no angular2 retorna um tipo Observable , no diretório de instalação do Angular2 ('node_modules' no meu caso), precisamos importar a função de mapa do Observable no seu componente usando o serviço http , como:

import 'rxjs/add/operator/map';
Amardeep Kohli
fonte
1

Angular 6 - apenas a importação 'rxjs / Rx' fez o truque para mim

Shimi Avizmil
fonte
1

Basta adicionar a linha no seu arquivo,

importar 'rxjs / Rx';

Importará várias dependências.Testado no angular 5

Mandeep Singh
fonte
0

É verdade que o RxJs separou seu operador de mapa em um módulo separado e agora você precisa explicitamente importá-lo como qualquer outro operador.

import rxjs/add/operator/map;

e você ficará bem.

Piyush Patel
fonte
0

A importação global é segura.

importar 'rxjs / Rx';

rotina xá
fonte
0
import 'rxjs/add/operator/map';

resolverá seu problema

Eu testei em angular 5.2.0 e rxjs 5.5.2

Mayank Bhardwaj
fonte
0

isso está acontecendo porque você está usando a função rxjs e in rxjs não é estático, o que significa que você não pode chamá-los diretamente. É necessário chamar os métodos dentro do pipe e importar essa função da biblioteca rxjs

Mas se você estiver usando rxjs-compat, basta importar os operadores rxjs-compat

Gurvinder Guraya
fonte
0

Eu tentei abaixo comandos e ele é corrigido:

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


import 'rxjs/Rx';
Phan Hero
fonte
Isso é apenas para você trabalhar inicialmente no rxjs 6 executando algumas correções para você. É apenas uma correção de curto prazo e a transição completa do rxjs 6 deve ser feita.
HankCa
0

importar {mapa} de 'rxjs / operadores';

isso funciona para mim em angular 8

user2900572
fonte
0

Além do que o @ mlc-mlapis comentou, você está misturando operadores permitidos e o método de aplicação de patches para protótipos. Use um ou outro .

Para o seu caso, deve ser

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';

@Injectable()
export class SwPeopleService {
    people$ = this.http.get('https://swapi.co/api/people/')
      .map((res:any) => res.results);

    constructor(private http: HttpClient) {} 
}

https://stackblitz.com/edit/angular-http-observables-9nchvz?file=app%2Fsw-people.service.ts

yogesh waghmare
fonte