notebook

都内でWEB系エンジニアやってます。

HttpClientでGetパラメータをセットする

angularのhttpクライアントは5系から@angular/httpではなく@angular/common/httpが推奨されています

既存のシステムが4系だったのでバージョンアップにあたり調査をしていたのですが少し詰まったところがあったのでメモを残しておきます

HttpClient

基本的にはinjectionしている箇所で読み込むモジュールを入れ替えればokだと思っていたのでまぁ楽勝だろうと思っていました

- import { Http } from '@angular/http';
+ import { HttpClient } from '@angular/common/http';
....
....
- constructor(private http: Http) {
+ constructor(private http: HttpClient) {
  ....
  ....
  ....
}

今まではgetの第二引数のoptionsにパラメータを渡していたのですがoptions.paramsの型もhttpとhttpClientで使うものが違うようです、コンパイルで怒られたので別の方法を探すことに

  • 怒られる
let options = new RequestOptions();
options.params = hash;

this.http.get(url,options).subscribe(

そもそもこの方法もちゃんとparamsの型指定してないので微妙なのですが動いていたのでこのままになってたという感じですね

「getリクエストのパラメータを引数で受け取ったハッシュそのまま投げたいんだけどどうしたら.....」

だいたいどのブログも下記のようにHttpParamsをnewしてsetもしくはappendしろといった感じのサンプルコードしかみつられませんでした

let params = new HttpParams().set('p1','v1').set('p2','p2')
let params = new HttpParams();
params = params.append('p1','v1')
params = params.append('p2','v2')

まぁこういう方法でもいいんですが、パラメータで配列渡したいとか、パラメータ増えた時とか、ループ回してやってくのはちょっとなーと思いました

個人的にはappendなのに返り値が返ってきてそれを使うみたいな感じとか

どうしても再代入が発生するような作りになりそうだったので毎度クエリ組み立てるためにこの処理入れないといけないのか?などと思い代案がないか探すことに

結局最初にやってたoptions.paramsの型エラーを対処する方が良さそうだったので探します

this.http.get(url,{params: params}).subscribe(

paramsの型はHttpParamsというものでした

HttpParams

Angular - HttpParams

https://angular-ja.firebaseapp.com/api/common/http/HttpParams#constructorangular-ja.firebaseapp.com

constructorでハッシュを受け取れそうな感じなのでこれに渡せばよしなにやってくれそうですね

ということで次はHttpParamsOptionsを見てみます

HttpParamsOptions

ドキュメントが12月末時点ではまだなさそうなのですがソース読んだらありました。

このinterfaceにしたがって定義すれば良さそう

fromObjectですね

angular/params.ts at master · angular/angular

ただこのfromObject、最近追加されたもののようです

masterのログだけ追った感じ9/26(5.0.0-rc1)にcommitされているのでその後にリリースされたもでないとfromObjectが使えないんですね

既存のコードのversionは4.4.3

残念!fromObject入ってませんw

ということでバージョンアップに伴う修正手順の選択肢は二つになりました

  1. バージョンアップ + コード修正(fromObjectを使う)一緒にやってしまう
  2. appendなどでお茶を濁してリリースしてからバージョンアップを実行

今回は1で一気に行くことに

ということでこんな感じのコードに落ち着きました

    const hash = {
      a: 'hoge',
      b: 'fuga',
      c: 'piyo'
    };

    const paramsOptions = <HttpParamsOptions>{fromObject: hash};
    const params = new HttpParams(paramsOptions);

    this.http.get(url,{params: params}).subscribe

ローカルでサーバ立ててリクエストの内容を確認しました

/?a=hoge&b=fuga&c=piyo HTTP/1.1" 200 -

まとめ

angular4 -> 5へのバージョンアップのための準備の一つ、httpの置き換えだったのですが実装によってはサクッとあげられるわけじゃないということがわかりました

ただ、今まで動いてるからまぁいいかとあまり深追いしなかったところだったのでコードまで読んで調査できたので理解が深まった気がします