2017.3.23
2017.4.17

GET/POSTデータ送信

Angular2でのHTTPメソッド(GETまたはPOST)でデータを送信する方法です。

Angularのチュートリアルを見ると、GET、POST、PUT、DELETEのHTTPメソッドが利用されていますが、この内、PUT、DELETEについてはサーバ側でも対応していないと使えません。

私の場合、サーバ側はRubyのSinatraを利用していて、SinatraでPUTまたはDELETEに対応するためには特別な対応(SinatraでHTTPメソッドのDELETEを実現する)が必要だったので、取得系はGET、登録系はPOSTというように、いつも通りな感じで利用しています。

また、HTTPヘッダーのContent-Type「application/json」にも対応していないようだったので、ヘッダーに関連する設定は省きました。

きちんとしたRESTfulなAPIを利用する場合は、参考リンクから公式サイトを確認してください。

目次

  • ディレクトリ、ファイルの構成
  • サービス
  • コンポーネント
  • 参考リンク

ディレクトリ、ファイルの構成

今回、試してみたディレクトリ、ファイルの構成は以下の通りです。

project
├ node_modules
└ src
    └ app
        ├ app.module.ts
        └ example
            ├ example.component.ts
            ├ example.service.ts
            └ example.ts

サービス

example.service.ts


import { Injectable } from '@angular/core';
import { URLSearchParams, Http } from '@angular/http';
import 'rxjs/add/operator/toPromise';
import { ExampleRow } from './example';

@Injectable()
export class ExampleService {
  private examplesUrl = 'http://localhost/examples';
  private exampleGetUrl = 'http://localhost/example/get';
  private exampleCreateUrl = 'http://localhost/example/create';
  private exampleUpdateUrl = 'http://localhost/example/update';
  private exampleDeleteUrl = 'http://localhost/example/delete';

  constructor(private http: Http) { }

  // 検索
  searchExample(params: URLSearchParams): Promise<ExampleRow[]> {
    return this.http.get(this.examplesUrl, { search: params })
      .toPromise()
      .then(response => response.json() as ExampleRow[])
      .catch(this.handleError);
  }

  // 取得
  getExample(id: number): Promise<ExampleRow> {
    return this.http.get(this.exampleGetUrl + '/' + id)
      .toPromise()
      .then(response => response.json() as ExampleRow)
      .catch(this.handleError);
  }

  // 作成
  createExample(data: any): Promise<any> {
    return this.http.post(this.exampleCreateUrl, JSON.stringify(data))
      .toPromise()
      .then(response => Promise.resolve(response))
      .catch(this.handleError);
  }

  // 更新
  updateExample(params: URLSearchParams, data: any): Promise<any> {
    return this.http.post(this.exampleUpdateUrl, JSON.stringify(data), { search: params })
      .toPromise()
      .then(response => Promise.resolve(response))
      .catch(this.handleError);
  }

  // 削除
  deleteExample(id: number): Promise<any> {
    return this.http.post(this.exampleDeleteUrl + '/' + id, null)
      .toPromise()
      .then(response => Promise.resolve(response))
      .catch(this.handleError);
  }

  handleError(error: any): Promise<any> {
    console.error('An error occurred', error);
    return Promise.reject(error.message || error);
  }
}

更新処理でURLにIDを含まずクエリパラメータを利用しているのは、そういったやり方もできるという確認のためです。

削除処理でPOSTを使う場合、引数のbodyにはとくに入れるものがないのでnullを設定しています。

コンポーネント

example.component.ts

(コードが長くなるのでHTMLは省いています。)


import { Component } from '@angular/core';
import { URLSearchParams } from '@angular/http';
import { ExampleRow } from './example';
import { ExampleService } from './example.service';

@Component({
  ...
  providers: [ExampleService]
})
export class ExampleComponent {
  constructor(
    private exampleService ExampleService
  ) { }

  exampleList: ExampleRow[] = [];
  example: ExampleRow;

  // 検索
  searchExample(): void {
    let params = new URLSearchParams();
    params.set('name', '検索文字列');

    this.exampleService.searchExample(params)
      .then (data  => { console.log('成功'); this.exampleList = data; })
      .catch(error => console.log('失敗'));
  }

  // 取得
  getExample(id: number): void {
    this.exampleService.getExample(id)
      .then (data  => { console.log('成功'); this.example = data })
      .catch(error => console.log('失敗'));
  }

  // 作成
  add(name: string, category: string): void {
    let data = {};
    data["name"] = name;
    data["category"] = category;

    this.exampleService.createExample(data)
      .then (data  => console.log('成功'))
      .catch(error => console.log('失敗'));
  }

  // 更新
  updateExample(example: Example): void {

    let params = new URLSearchParams();
    params.set('id', example.id);

    let data = {};
    data["name"] = example.name;
    data["category"] = example.category;

    this.exampleService.updateExample(params, data)
      .then (data  => console.log('成功'))
      .catch(error => console.log('失敗'));
  }

  // 削除
  deleteExample(id: number): void {
    this.exampleService.deleteExample(id)
      .then (data  => console.log('成功'))
      .catch(error => console.log('失敗'));
  }

example.ts


export class ExampleRow {
  id: number;
  name: string;
  category: string;
}

関係ありそうなところを抜粋して記事用にクラスやメソッド名を変更したので、そのままじゃ動かないかも...

参考リンク

Angular】関連記事