AngularでJsonpを使いデータを受信する

AngularでJsonpを使ってデータを受信する方法を説明します。

ざっくりまとめると以下のような事をします。

  • HttpClientModuleとHttpClientJsonpModuleをインポートする。
  • HttpClient.jsonp()メソッドでリクエストする。

他はObservableを使うなど、jsonpとは関係ない部分ですが例を示します。

 

以下、サンプルコードと説明です。

 

まずapp.module.ts でHttpClientModule とHttpClientJsonpModule をimportします。

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
// ↓ここ追加
import { HttpClientModule, HttpClientJsonpModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule, // ← ここ追加
    HttpClientJsonpModule // ← ここ追加
  ],
  providers: [],
  bootstrap: [
    AppComponent
  ]
})

ちなみにこれを追加しておかないと実行時に以下のようなエラーが出ます。

Error: StaticInjectorError[HttpClient]: 
  StaticInjectorError[HttpClient]: 
  NullInjectorError: No provider for HttpClient!

 

次にサービスなどからhttpリクエストしてJsonpを処理します。

import { Injectable } from '@angular/core';
import { Hoge } from './hoge';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';
const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json'})
};

@Injectable({
  providedIn: 'root'
})
export class HogeService {

  private hogeUrl = 'https://hoge.app/hoge';

  constructor(
    private http: HttpClient
  ) { }

  getHoge(): Observable<Hoge[]> {
    // ↓ hogeUrlにリクエストして、Jsonpのcallbackを呼び出し、Hoge配列として返す。(ObservableでPublishする)
    return this.http.jsonp<Hoge[]>(this.hogeUrl, "callback")
      .pipe(
        catchError(this.handleError('getHoge', []))
      )
  }

  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);
      return of(result as T);
    }
  }
}

hogeは以下のような感じで定義しているとします。

export class Book {
  id:number;
  title:string;
}

コンポーネントからはSubscribeで結果を受け取ります。

import { Component, OnInit } from '@angular/core';
import { HogeService } from './hoge.service'
import { Hoge } from './hoge'

@Component({
selector:'app-hoge',
  templateUrl:'./hoge.component.html',
  styleUrls: ['./hoge.component.css']
})
export class HogeComponent implements OnInit {
  hoges: Hoge[];

  constructor(
    private hogeService: HogeService
  ) { }

  getHoge():void {
    // ↓ サービス経由で受信したデータを受け取る。
    this.hogeService.getHoge()
      .subscribe(hoges => this.hoges = hoges);
  }

  ngOnInit() {
    this.getHoge();
  }

}

テンプレートは以下のような感じ。

<ul>
  <li*ngFor="let hoge of hoges">
    title:{{ hoge.title }}
  </li>
</ul>

 

以上です。

タイトルとURLをコピーしました