Http.get (…) .map TypeScript hatası içeren açısal HTTP GET [null] öğesinde bir işlev değil


334

Angular'da HTTP ile ilgili bir sorunum var.

Sadece GETbir JSONliste yapmak ve görünümde göstermek istiyorum .

Servis sınıfı

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

Ve yöntemi hizmetten HallListComponentçağırıyorum getHalls:

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

Ancak, bir istisna var:

TypeError: this.http.get (...). Harita [null] içinde bir işlev değil

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

Http.get bir söz vermiyor mu?
bmm6o

1
@ bmm6o Yeni Httphizmet gözlemlenebilir bir değer döndürüyor
Brocco

1
Bir projeyi Angular2 beta-17'den nihai sürüme geçirmeye çalışırken neredeyse özdeş bir sorunla karşılaştım. Sorun benim VSE, VS 2015, Güncelleme 3 1.8.36kullanarak oldu "typescript": "^2.0.2". TS dilinin yükseltilmesi. uzantıları ve Güncellemeler aracılığıyla hizmet benim için hile yaptı. Bu güncelleme yüklenirken , aynı sonuca varılan bu SO cevabına rastladım .
Eric Lease

Phpstorm / webstorm için, daktilo versiyonunun projemin kütüphanesiyle güncellenmesi de sorunu çözdü. Bu SO cevabının adımlarını takip ettim: stackoverflow.com/a/31608934/1291428
Sebas

Yanıtlar:


538

Bunu içe aktarmanız gerektiğini düşünüyorum:

import 'rxjs/add/operator/map'

Ya da daha genel olarak gözlemlenebilirler için daha fazla yöntem istiyorsanız. UYARI: Bu işlem 50'den fazla operatörün tamamını içe aktarır ve uygulamanıza ekler, böylece paket boyutunuzu ve yükleme sürelerinizi etkiler.

import 'rxjs/Rx';

Daha fazla ayrıntı için bu konuya bakın.


1
Hangi hatalar hala mevcut? Bu konuda stackoverflow ;-) hakkında bazı özel sorular sorabilirsiniz Bu soru belki de size yardımcı olabilir: stackoverflow.com/questions/34450131/… .
Thierry Templier

1
Açısal 2 RC 0'dan itibaren, bu artık gerekli değildir.
Onur Yıldırım

3
@ OnurYıldırım, rc.4 kullanarak, yanlış bir şey yapmadıkça bu içe aktarma işlemi hala gereklidir.
Joseph Gabriel

18
Lütfen 'import' rxjs / Rx 'kullanmayın;' çünkü her şeyi ithal eder ve rxjs oldukça büyük olma eğilimindedir. Operatörleri istediğiniz gibi tek tek içe aktarın.
Drag0

1
Rxjs ile Açısal 2: 5.0.0-beta.12 burada. Ve hala yapmak zorundaydım import 'rxjs/add/operator/do'... .map()Artık bunu yapmak zorunda değiliz. Ama bu benim .do()durumuma yardımcı oldu , özellikle onu içe aktarmam gerektiğini fark ettim. Teşekkür ederim! Benden bir oy :)
MrCroft

82

Sadece biraz arka plan ... Yeni basılan Sunucu İletişimi geliştirme kılavuzu (nihayet) bunu tartışıyor / bahsediyor / açıklıyor:

RxJS kütüphanesi oldukça büyük. Bir üretim uygulaması oluşturup mobil cihazlara dağıtırken boyut önemlidir. Sadece gerçekten ihtiyacımız olan özellikleri dahil etmeliyiz.

Buna göre Angular Observable, rxjs/Observablemodülde sökülen bir versiyonunu ortaya çıkarır ; bu , burada kullanmak istediklerimiz dahil olmak üzere neredeyse tüm operatörlerden yoksun bir versiyonmap yöntem .

İhtiyacımız olan operatörleri eklemek bize kalmış. Gereksinimlerimize tam olarak uyarlanmış özel bir Gözlemlenebilir uygulama olana kadar her bir operatörü tek tek ekleyebiliriz.

@Thierry zaten cevap verdiğinden, ihtiyacımız olan operatörleri çekebiliriz:

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

Ya da tembelsek, operatörlerin tamamını çekebiliriz. UYARI: Bu, uygulama paketinize 50'den fazla operatörün tamamını ekler ve yükleme sürelerini etkiler

import 'rxjs/Rx';

2
ithalat 'rxjs / Rx'; vay. ve tüm saçlarım anında çekiliyor. Bu Rxjs / Angular2 için tüm dünyada basılmaz inanamıyorum. Teşekkürler!!!
JimB

Ancak sıklıkla tüy bırakmaz, varsayılan olarak kara listeye alınmış bir içe aktarmadır. Yeni bir açısal CLI projesi oluşturun, göreceksiniz. Kolaylığı kendim seviyorum ama NYC çalıştığım yerlerde kongre yapmak değil.
Tim Consolazio

21

Dan 5.5 rxjs itibaren kullanabileceğiniz pipeable operatörleri

import { map } from 'rxjs/operators';

Sorun nedir import 'rxjs/add/operator/map';

Bu yaklaşımı kullandığımızda mapoperatör yamalı observable.prototype ve bu nesnenin bir parçası haline gelecektir .

Daha sonra, mapoperatörü gözlemlenebilir akışı işleyen koddan kaldırmaya karar verirseniz, ancak karşılık gelen içe aktarma ifadesini kaldıramazsanız, uygulayan kodun mapbir parçası olarak kalır Observable.prototype.

Paketçiler kullanılmayan kodu ( aka tree shaking ) ortadan kaldırmaya çalıştığında map, uygulamada kullanılmasa bile operatörün kodunu Gözlemlenebilir'de tutmaya karar verebilirler .

Çözüm -Pipeable operators

Kablolanabilir operatörler saf işlevlerdir ve Gözlemlenebilirleri yamalamazlar . ES6 içe aktarma sözdizimini kullanarak işleçleri içe aktarabilir import { map } from "rxjs/operators"ve sonra bunları bir işleve sarabilirsinizpipe() değişken sayıda parametre alan bir , yani zincirlenebilir işleçlere sarabilirsiniz.

Bunun gibi bir şey:

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

16

Açısal 5 ile RxJS içe aktarımı geliştirildi.

Onun yerine

import 'rxjs/add/operator/map';

Şimdi yapabiliriz

import { map } from 'rxjs/operators';

Bu yaklaşımı kullanarak, şimdi yapınızda sadece kullanılmış operatörleri (bu durumda harita) içerecek, daha önce rxjs kütüphanesinden tüm operatörleri içermekteydi. daha fazla ayrıntı için aşağıdaki bağlantıyı kontrol edin. loiane.com/2017/08/angular-rxjs-imports
Hiren Shah

13

Observable.subscribeDoğrudan kullanmak işe yaramalıdır.

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

5
Bu çok verimli bir yaklaşım değil. Örneğin, birden fazla abone varsa, her biri hizmette bir kez yapmak yerine veriler üzerinde harita çalıştırmalıdır. Bence OP doğru yaklaşıma sahipti, sadece kullanmak için doğru modüle sahip değildi.
Evan Plaice

3

Açısal sürüm 5 ve üstü için, güncellenen içe aktarma satırı aşağıdaki gibi görünür:

import { map } from 'rxjs/operators';

VEYA

import { map } from 'rxjs/operators';

Ayrıca bu sürümler Pipable Operators'ı tamamen destekler, böylece .pipe () ve .subscribe () işlevlerini kolayca kullanabilirsiniz.

Açısal sürüm 2 kullanıyorsanız, aşağıdaki satır kesinlikle iyi çalışmalıdır:

import 'rxjs/add/operator/map';

VEYA

import 'rxjs/add/operators/map';

Hâlâ bir sorunla karşılaşıyorsanız, şunları yapmalısınız:

import 'rxjs/Rx';

Bunu doğrudan kullanmanızı tercih etmeyeceğim bcoz, Yükleme süresini artırır, çünkü endüstri normlarına göre iyi bir uygulama olmayan çok sayıda operatör (faydalı ve yararlı olmayanlar) vardır, bu yüzden emin olun önce yukarıda belirtilen içe aktarma hatlarını kullanmayı denersiniz ve bu işe yaramazsa rxjs / Rx için gitmelisiniz


3

Bu sorunun bir çözümü var

Bu paketi yükle:

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

o zaman bu kütüphaneyi içe aktar

import 'rxjs/add/operator/map'

nihayet iyonik projenizi yeniden başlatın

ionic serve -l

3

Açısal sürüm 6 "0.6.8" rxjs sürüm 6 "^ 6.0.0"

bu çözüm:

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

Hepimizin bildiği gibi açısal her gün geliştiriliyor, bu yüzden her gün birçok değişiklik var ve bu çözüm
ilk olarak açısal 6 ve rxjs 6 için http yo ile çalışmak gerekir: sonuçta app HttpModule bildirmek zorunda. module.ts

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

ve Ngmodule'ye HttpModule eklemeniz gerekiyor -> ithalat

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

ikinci harita ile çalışmak için önce boru ithal etmelisiniz:

import { pipe } from 'rxjs';

üçüncü harita fonksiyonu ithalat gerekir gerekir:

import { map } from 'rxjs/operators';

haritayı boru içinde bu örnek gibi kullanmanız gerekir:

 constructor(public http:Http){  }

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

bu iyi çalışır iyi şanslar!


2

Haritası burada kullanarak değil .map()javascript, bu çalışan Rxjs haritası işlevi var Observablesaçısal içinde ...

Dolayısıyla, sonuç verilerinde haritayı kullanmak istiyorsanız onu içe aktarmanız gerekir ...

map(project: function(value: T, index: number): R, thisArg: any): Observable<R> Belirli bir proje işlevini Gözlemlenebilir kaynağı tarafından yayılan her değere uygular ve ortaya çıkan değerleri Gözlenebilir olarak yayar.

Yani basitçe şu şekilde içe aktarın:

import 'rxjs/add/operator/map';

1

Yana Http hizmete angular2 dönüşleri bir Gözlenebilir türü, Angular2 yükleme dizininden (benim durumumda 'node_modules'), Biz de gözlemlenebilir ithalat haritası fonksiyonuna ihtiyaç bileşeni kullanarak http olarak, hizmet:

import 'rxjs/add/operator/map';


1

Sadece satırı dosyanıza ekleyin,

ithalat 'rxjs / Rx';

Bağımlılık demetini ithal edecek. 5


0

Doğru, RxJs harita operatörünü ayrı bir modülde ayırdı ve şimdi onu başka bir operatör gibi içe aktarmanız gerekiyor.

import rxjs/add/operator/map;

ve iyi olacaksın.



0
import 'rxjs/add/operator/map';

problemini çözecek

Açısal 5.2.0 ve rxjs 5.5.2'de test ettim


0

bu oluyor çünkü rxjs kullanıyorsunuz ve rxjs fonksiyonunda statik değilsiniz, bu da onları doğrudan arayamazsınız, boru içindeki yöntemleri çağırmanız ve bu fonksiyonu rxjs kütüphanesinden içe aktarmanız gerekir.

Ama eğer rxjs-compat kullanıyorsanız sadece rxjs-compat operatörlerini içe aktarmanız gerekir


0

Aşağıdaki komutları denedim ve düzeltildi:

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


import 'rxjs/Rx';

Bu sadece başlangıçta sizin için bazı yama uygulayarak rxjs 6'da çalışmanızı sağlamaktır. Sadece kısa süreli bir düzeltmedir ve tam rxjs 6 geçişi yapılmalıdır.
HankCa

0

{map} 'rxjs / operatörlerinden içe aktar;

bu açısal 8 benim için çalışıyor


0

Ayrıca @ mlc-mlapis ne yorum yaptı, izin verilen operatörleri ve prototip yama yöntemini karıştırıyorsunuz. Birini veya diğerini kullanın .

Sizin durumunuz için olmalı

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.