TypeScriptエラーを伴うAngular HTTP GET http.get(…).mapは[null]の関数ではありません


334

AngularのHTTPに問題があります。

私はちょうどにしたいリストビューで表示されます。GETJSON

サービスクラス

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

そして、HallListComponentgetHallsはサービスからメソッドを呼び出します:

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

ただし、例外が発生しました:

TypeError:this.http.get(...)。mapは[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"
  ]
}

http.getはpromiseを返しませんか?
bmm6o 2015

1
@新しいbmm6o Httpサービス戻り、観察
Brocco

1
私はほぼ同じ問題に遭遇し、プロジェクトをAngular2ベータ-17から最終リリースに移行しようとしました。私にとっての問題はIDEでしたが、VS 2015、Update 3を使用1.8.36しています。TypeScript 言語サービス拡張はまだでしたが、ng2クイックスタートガイド(これを書いている)はを使用してい"typescript": "^2.0.2"ます。TS言語のアップグレード。Extensions and Updatesを介したサービスでうまくいきました。その更新がインストールされている間に私はこのSOの答えに出くわしましたが、同じ結論で終わります。
Eric Lease

phpstorm / webstormの場合、私のプロジェクトのライブラリを使用してtypescriptバージョンを更新すると、問題も解決しました。私はこのSOの回答の手順を実行しました:stackoverflow.com/a/31608934/1291428
Sebas

回答:


538

これをインポートする必要があると思います:

import 'rxjs/add/operator/map'

より一般的には、オブザーバブルのメソッドを増やしたい場合に使用します。 警告:これにより、50以上の演算子がすべてインポートされ、アプリケーションに追加されるため、バンドルサイズとロード時間に影響します。

import 'rxjs/Rx';

詳細については、この問題を参照してください。


1
まだ残っているエラーはどれですか?stackoverflowでこれに関するいくつかの特定の質問をすることができます;-)この質問もおそらく役立つかもしれません:stackoverflow.com/questions/34450131/…
Thierry Templier

1
Angular 2 RC 0以降、これは不要になりました。
OnurYıldırım16年

3
@OnurYıldırım、rc.4を使用する場合、私が何か間違っていない限り、このインポートはまだ必要です。
ジョセフガブリエル

18
「import 'rxjs / Rx';」は使用しないでください。すべてをインポートし、rxjsはかなり大きくなる傾向があるためです。必要に応じて、演算子を1つずつインポートします。
Drag0

1
Angular 2とrxjs:5.0.0-beta.12はこちら。そして、私はまだしなければなりimport 'rxjs/add/operator/do'ませんでした... .map()もうこれをする必要はありませんが。しかし、これは私の.do()場合に役立ちました。具体的にインポートする必要があることに気づきました。ありがとうございました!私からの賛成票:)
MrCroft 2016

82

ほんの一部の背景...新しく作成されたサーバー通信開発ガイド(これは最終的に)について議論/言及/説明しています:

RxJSライブラリは非常に大きいです。本番アプリケーションを作成してモバイルデバイスに展開する場合、サイズが重要になります。実際に必要な機能のみを含める必要があります。

したがって、AngularはObservablerxjs/Observableモジュール内のの削除されたバージョンを公開します。このバージョンには、mapメソッドなど、ここで使用したい演算子を含め、ほとんどすべての演算子がありません。

必要な演算子を追加するのは私たち次第です。カスタムのObservable実装が要件に正確に調整されるまで、各演算子を1つずつ追加することができます。

したがって、@ Thierryがすでに回答したように、必要な演算子を取り込むだけです。

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

または、怠惰な場合は、演算子の完全なセットを取得できます。警告:これにより、50以上の演算子がすべてApp Bundleに追加され、読み込み時間が影響を受けます

import 'rxjs/Rx';

2
'rxjs / Rx'をインポートします。ワオ。髪の毛を引っ張っているとすぐに消えます。これがRxjs / Angular2の世界中で印刷されていないなんて信じられません。ありがとう!!!
JimB 2016年

しかし、それはしばしばリントされません、デフォルトでそれはブラックリストにされたインポートです。新しいAngular CLIプロジェクトを作成します。私自身も便利さを気に入っていますが、ニューヨークで働く場所での慣習はそうすることではありません。
Tim Consolazio

21

rxjs 5.5以降では、使用することができますpipeable演算子を

import { map } from 'rxjs/operators';

何が問題になっていますか import 'rxjs/add/operator/map';

このアプローチを使用すると、map演算子がパッチされobservable.prototype 、このオブジェクトの一部になります。

後でmap、監視可能なストリームを処理するコードから演算子を削除することを決定したが、対応するインポートステートメントの削除に失敗した場合、実装するコードmapはの一部のままObservable.prototypeです。

バンドラーが未使用のコード(別名 tree shaking)を削除しようとするmapと、アプリケーションで使用されていなくても、オペレーターのコードをObservable に保持することを決定する場合 があります。

ソリューション -Pipeable operators

パイプ可能演算子は純粋な関数であり、Observableにパッチを適用しません。ES6のインポート構文を使用して演算子をインポートし、可変数のパラメーターを取るimport { map } from "rxjs/operators"関数pipe()、つまりチェーン可能な演算子にそれらをラップすることができます。

このようなもの:

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

16

Angular 5ではRxJSのインポートが改善されています。

の代わりに

import 'rxjs/add/operator/map';

できるよ

import { map } from 'rxjs/operators';

このアプローチを使用すると、現在のビルドでは使用された演算子(この場合はマップ)のみが含まれ、以前はrxjsライブラリのすべての演算子が含まれていました。詳細については、以下のリンクを確認してください。 loiane.com/2017/08/angular-rxjs-imports
Shah

13

Observable.subscribe直接使用する必要があります。

@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
これは非常に効率的な方法ではありません。たとえば、複数のサブスクライバーがいる場合、サービスで一度だけ実行するのではなく、それぞれがデータに対してマップを実行する必要があります。OPには適切なアプローチがあったと思いますが、それを使用するための適切なモジュールがロードされていませんでした。
Evan Plaice、2016年

3

Angularバージョン5以降の場合、更新されたインポート行は次のようになります。

import { map } from 'rxjs/operators';

または

import { map } from 'rxjs/operators';

また、これらのバージョンはPipable演算子を完全にサポートしているため、.pipe()および.subscribe()を簡単に使用できます。

Angularバージョン2を使用している場合は、次の行が完全に機能するはずです。

import 'rxjs/add/operator/map';

または

import 'rxjs/add/operators/map';

それでも問題が発生する場合は、以下を実行する必要があります。

import 'rxjs/Rx';

bcozを直接使用することはお勧めしません。この演算子には多数の演算子が含まれているため(有用なものと有用でないもの)、業界の規範によると適切ではありません。上記のインポート行を最初に使用してみて、それが機能しない場合は、rxjs / Rxを使用する必要があります


3

この問題の解決策があります

このパッケージをインストールします。

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

次に、このライブラリをインポートします

import 'rxjs/add/operator/map'

最後に、イオンプロジェクトを再起動します。

ionic serve -l

3

Angularバージョン6 "0.6.8" rxjsバージョン6 "^ 6.0.0"

このソリューションは、

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

Angularは毎日開発されているため、毎日多くの変更があり、このソリューションはAngular 6とrxjs 6が
最初にhttpで動作するためのものです。インポートする必要があるので、アプリでHttpModuleを宣言する必要があります。 module.ts

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

HttpModuleをNgmoduleに追加する必要があります-> インポート

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

次にマップを操作するには、最初にパイプをインポートする必要があります。

import { pipe } from 'rxjs';

3番目に、マップ関数importが必要です:

import { map } from 'rxjs/operators';

次の例のように、パイプ内のマップを使用する必要があります。

 constructor(public http:Http){  }

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

それは完全に幸運です!


2

マップあなたがここに使用しては、ない.map()に取り組んJavaScriptで、それのRxjsマップ機能Observables角度で...

そのため、結果データにマップを使用する場合は、インポートする必要があります...

map(project: function(value: T, index: number): R, thisArg: any): Observable<R> ソースのObservableによって発行された各値に特定のプロジェクト関数を適用し、結果の値をObservableとして発行します。

したがって、次のようにインポートするだけです。

import 'rxjs/add/operator/map';

1

angular2のHttpサービスはObservableタイプを返しますので、Angular2インストールディレクトリ(私の場合は「node_modules」)から、次のようにhttpサービスを使用してコンポーネントに Observableのマップ関数をインポートする必要があります:

import 'rxjs/add/operator/map';


1

ファイルに行を追加するだけで、

'rxjs / Rx'をインポートします。

一連の依存関係をインポートします。角度5でテスト


0

確かに、RxJsはマップ演算子を別のモジュールに分離しているため、他の演算子と同様に明示的にインポートする必要があります。

import rxjs/add/operator/map;

そして、あなたは元気になります。




0

これは、rxjsを使用しており、rxjs関数が静的ではないために発生しています。つまり、それらを直接呼び出すことはできず、パイプ内のメソッドを呼び出して、rxjsライブラリからその関数をインポートする必要があります。

ただし、rxjs-compatを使用している場合は、rxjs-compat演算子をインポートするだけです


0

以下のコマンドを試してみましたが、修正されました:

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


import 'rxjs/Rx';

これは、最初にrxjs 6でいくつかのパッチを適用して作業させるためのものです。これは短期的な修正であり、rxjs 6への完全な移行を行う必要があります。
HankCa


0

さらに、@ mlc-mlapisがコメントしたように、lettable演算子とプロトタイプのパッチメソッドを混在させています。どちらか一方を使用してください

あなたの場合、それは

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.