##動機##
AngularJSでアプリケーションを構築しているのにもかかわらず、
HTTPリクエストをjQueryに頼っていた僕ですが、
幾度もチームメンバーからの冷ややかな目線を感じてましたので、
$httpに乗り換えてやろうと決意しました。
##まずは$.ajaxコードを確認してみましょう。##
let queries = {
"name": "Donald John Trump",
"birthday": "1946-06-14",
"money": NaN
}
$.ajax({
type: "POST",
url: "https://example.com/api/action",
data: queries,
dataType: "json",
success: function (response, status, xhr) {
//成功
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
//失敗
}
});
うん、実に単純、これは手間かからなそうだ。
かっこつけてES6使ったろ(ドヤ顔
##早速$httpに書き換えましょう##
let queries = {
"name": "Donald John Trump",
"birthday": "1946-06-14",
"money": NaN
}
$http({
method: "POST",
url: "https://example.com/api/action",
data: queries,
responseType: "json"
}).then(
(response) => {
//成功
},
(errors) => {
//失敗
}
);
これは、ほぼ一緒だな、楽勝すぎる。
早速ビルドして送ってみましょう!
##Responseを確認##
400 Bad Request
むぅ...なるほど、
一つだけ言えるのは、
僕はこの数字が嫌いだ。
そこでAPIから帰ってきたメッセージを読んでみると、
"message": "不正なパラメーターです"
ご親切にありがたいですね、リクエストの中身を見てみましょう。
##Request Dataを確認##
"name": "Donald John Trump",
"birthday": "1946-06-14",
"money": NaN
あれ?
一見なんの変哲も無いdataなんですが...
$.ajax時代のものと比較してみましょう!
name=Donald John Trump&birthday=1946-06-14&money=NaN
あっ...これは...まさかjsonで送っているとは、
粋なことしてくれるなぁ
仕方が無い、headerを書き換えよう
##再度チャレンジ##
// ...
$http({
method: "POST",
url: "https://example.com/api/action",
headers: {
//ヘッダーに追加してあげましょう
'Content-Type': 'application/x-www-form-urlencoded'
},
data: queries,
responseType: "json"
}).then(
(response) => {
//成功
},
(errors) => {
//失敗
}
);
さー、こい。
##Responseを確認(2度目)##
400 Bad Request
"message": "不正なパラメーターです"
なるほど。
デジャブでしょうか。
再度リクエストの中身を確認しましょう。
"name": "Donald John Trump",
"birthday": "1946-06-14",
"money": NaN
これはあれかね、
Content-TypeをAngularは見ていないのかね!?
おばかさんなのかね!?(半ギレ
##とりあえず解決(?)##
仕方が無い、手動で変換して差し上げましょう
// ...
$http({
// ...
data: queryString.stringify(queries),
// ...
);
let queryString = {
parse: (text = location.search.substr(1), isDecode = false) => {
const decode = (isDecode) ? decodeURIComponent : a => a;
return text.split('&').reduce((obj, v) => {
var pair = v.split('=');
obj[pair[0]] = decode(pair[1]);
return obj;
}, {});
},
stringify: (value, isEncode = false) => {
const encode = (isEncode) ? encodeURIComponent : a => a;
return Object.keys(value).map(key => `${key}=${encode(value[key])}`).join('&');
},
};
これで無事に動きました。
めでたし、めでたし。
って言いたいところですが、
これをAngularがサポートしてくれないわけが無い、
きっと僕の知らない魔法がどこかあるはず!
##結論##
- Angularはhttpリクエスト時にjsonでのやり取りを推奨している (公式ドキュメントでも明記)
-
$httpはおバカであるor 僕がおバカである - ES6は使ってて気持ちが良い
- 僕は400番が嫌いだ
jQuery($.ajax)の方が楽- [追伸]
$httpParamSerializerJQLike
で解決!
何か他に文明の利器は無いのでしょうか、
ちなみに他のhttpリクエスト系ライブラリーは今の所使う予定無いです。
なにかいい情報がありましたらご教授願いたいです...m(_ _)m
##追伸##
コメントでいただいた通り、 $http
のドキュメントでPOSTされたものは全てJSONにしてやるぞ!と書いてありましたねーむぅ。
そして同じく頂いたコメント通りに $httpParamSerializerJQLike
実装をしたら無事にできました!
\(^〇^)/アリガタヤアリガタヤ\(^〇^)/