非同期通信の実行 Httpサービス(P4762)

サービスを使わない場合

API

backend/app.go

package main

import (
    "encoding/json"
    "net/http"
)

func init() {
    http.HandleFunc("/apis/user", func(w http.ResponseWriter, r *http.Request) {
        u := User{Name: r.FormValue("name")}
        res, err := json.Marshal(u)
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        w.Header().Set("Content-Type", "application/json")
        w.Write(res)
    })
}

type User struct {
    Name string `json:"name"`
}

app.yaml

application: angular-gae-go-test
version: 1
runtime: go
api_version: go1.8

handlers:
- url: /apis/(.*)
  script: _go_app
- url: /(.*\.(gif|png|jpeg|jpg|css|js|ico))$
  static_files: dist/\1
  upload: dist/(.*)
- url: /(.*)
  static_files: dist/index.html
  upload: dist/index.html

angular app

sample-app/src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule }      from '@angular/core';
import { FormsModule }   from '@angular/forms';
import { HttpModule} from '@angular/http';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule
  ],
  providers: [ ],
  bootstrap: [AppComponent]
})
export class AppModule { }

sample-app/src/app/app.component.ts

import { Component } from '@angular/core';
import { Http, URLSearchParams, Headers }  from '@angular/http';

@Component({
  selector: 'app-root',
  template: `
    <form>
      <label for="name">名前:</label>
      <input id="name" name="name" type="text" [(ngModel)]="name" />
      <input type="button" (click)="onclick()" value="送信" />
    </form>
    <div>{{result}}</div>
  `,
})
export class AppComponent {
  name = '';
  result = '';

  constructor(private http: Http) { }

  onclick() {
    // this.http.get('apis/user', {
    //   params: { name: this.name }

    //  URLSearchParamsで渡す場合
    let ps = new URLSearchParams();
    ps.set('name', this.name);
    this.http.get('apis/user', {
      params: ps

    /*
    // POST による通信の場合
    let ps = new URLSearchParams();
    ps.set('name', this.name);
    this.http.post('app/http.php', ps, {
      headers: new Headers({
        'Content-Type': 'application/x-www-form-urlencoded'
    })
    */

    /*
    //JSON形式で送信
    this.http.post('app/http.php', { name: this.name }, {
      headers: new Headers({ 'Content-Type': 'application/json' })
    */

      })
      .subscribe(
        response => {
          this.result = response.json().name;
        },
        error => {
          this.result = `通信失敗:${error.statusText}`;
        }
      );
  }
}

user.ts

export class User {
  name: string;
}

サービスに切り出す場合

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule }      from '@angular/core';
import { FormsModule }   from '@angular/forms';
import { HttpModule} from '@angular/http';

import { AppComponent } from './app.component';
import { UserService }  from './user.service'; // サービス登録

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule
  ],
  providers: [ UserService ], // サービス登録
  bootstrap: [AppComponent]
})
export class AppModule { }

user.service.ts

import { Injectable } from '@angular/core';
import { User } from './user';
// import { HttpModule} from '@angular/http';
import { Observable } from 'rxjs/Observable'
import { Http, URLSearchParams, Headers }  from '@angular/http';
import 'rxjs/add/operator/map'

@Injectable() // Ingectableデコレーターを付与するとコンポーネントに対してサービスを引き渡せる
export class UserService {
  constructor(private http: Http) { }
  getUser(name: string): Observable<User>{ // 戻り値はUserモデル
    let ps = new URLSearchParams();
    ps.set('name', name);
    return this.http.get('apis/user', {
      params: ps
    }).map(res=>res.json() as User);
  }
}

sample-app/src/app/app.component.ts

import { Component } from '@angular/core';
import { Http, URLSearchParams, Headers }  from '@angular/http';
import { UserService } from './user.service';

@Component({
  selector: 'app-root',
  template: `
    <form>
      <label for="name">名前:</label>
      <input id="name" name="name" type="text" [(ngModel)]="name" />
      <input type="button" (click)="onclick()" value="送信" />
    </form>
    <div>{{result}}</div>
  `,
})
export class AppComponent {
  name = '';
  result = '';

  constructor(private userService: UserService) { } // userServiceの注入

  onclick() {
    this.userService.getUser(this.name).subscribe(
      response => {
        this.result = response.name + "!"; // responseはuserモデル
      },
      error => {
        this.result = `通信失敗:${error.statusText}`;
      }
    );
  }
}

参考

https://qiita.com/lacolaco/items/364c5923f77458c468ac