はじめに
私は今までバックエンドとしてサーバー周りだったり、apiがどうのこうのを主にGolangで作業をしてたのですが、この度フロントエンドをやってみることに。
表側もかなり大変ですね ~
javascriptとは
Javaとは別物の言語でオブジェクト指向型スクリプト言語だが、クラスの概念もあると。
なんだか面白そうだと思いました。
今回は引数でmethodやendopoint,パラメーター,必要なcolumn情報(DB)を渡してレスポンスを得る関数を作成しただけですので、クラス等はまた今度。
XMLHttpRequest
さて、早速調べていくのですが、早速いいもの見つけました。
XMLHttpRequestというのがあるじゃないですか。
XMLHttpRequestとは。
Ajax(非同期通信)で使われる組み込みオブジェクトのことで、サーバーへ通信リクエストが送れるようになる。とのことです。
コーディング開始
もうこれ使うしかないなと思って、早速調べながらコーディングを始めました。
で、一番最初に書いたコードがこちら ...
function get_login_info_response(method, endpoint, parameters) {
// XMLHttpRequestオブジェクトを作成
var request = new XMLHttpRequest();
// Httpリクエストに必要な情報
request.open(method, endpoint);
request.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
request.responseType = 'json';
// 実行
request.onload = function() {
response_from_database = this.response;
console.log(response_from_database);
true_or_false = response_from_database['is_admin'];
console.log(true_or_false);
return true_or_false
};
// Httpリクエストを送信(引数指定で特定の情報のみを送信)
request.send(parameters);
}
「js始めて全然月日経ってないのこのコード割と使えるんじゃ!?」
って思ってましたが、色々と不備が多いです。
まず一番やらかしてるのは、.onload内のスコープで返り値出そうとしていることですよね。
これは絶望的です、やっちゃってますね。
これhtml側から関数呼んでも、スコープがズレてるのでコンソールには"undefined"と表示されちゃうんです。
そして、処理が一方通行です。http.statusでステータスコードを判別して処理を書くべきです。401が渡された時にエラーも何も表示されないとユーザー側は何が起こったか理解できないじゃないかと。
返り値をちゃんともらうのに結構苦労しました。
こんなコードも書きました。
a = request.onload = function () {
...
}
return a
血迷っちゃったんでしょうか。
.onloadで取得した結果をそのままreturnしようとしたんです ...
反省してます。
いくつもの試行錯誤を重ね、最終的にたどり着いたコードが以下です。
function get_login_info_response(method, endpoint, parameters, callback) {
// XMLHttpRequestオブジェクトを作成
var request = new XMLHttpRequest();
// Httpリクエストに必要な情報
request.open(method, endpoint);
request.setRequestHeader('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
request.responseType = 'json';
// 実行
request.onload = function() {
response_from_database = this.response;
// ステータスコードによって処理を変更
if (request.status === 401) {
alert("IDかパスワードが違います。");
console.log(response_from_database);
} else if (request.status === 200) {
true_or_false = response_from_database['is_admin'];
console.log(true_or_false);
}
callback(true_or_false)
};
// Httpリクエストを送信(引数指定で特定の情報のみを送信)
request.send(parameters);
}
最終的にたどり着いた答えはcallback関数でした。
ここでcallback関数について書いても長くなるだけなので、
callback関数とはをご参照くださいませ。
これでhtml側からうまく返り値を受け取れて、trueかfalseによってログインの処理ができるようになりました。
まとめ
割と綺麗にコードが書けたんじゃないかなと自画自賛しちゃいましたが、javascriptが達者な方から見たらどうなんでしょうか ... 気づいた方がいらっしゃいましたらお気軽にご指摘していただけると幸いです。
ご参考にさせていただいた主なサイト様
https://qiita.com/sirone/items/412b2a171dccb11e1bb6
こちらの記事は特に大変参考になりましたありがとうございます。
*6月6日 更新
この後、色々と記事を見ながらもっと使いやすい関数にするために試行錯誤し、今現在のコードはこうなりました。
function apiResponse(method, endpoint, key, parameters, callback) {
// XMLHttpRequestコンストラクタを作成
var request = new XMLHttpRequest();
// ハンドラー
request.onreadystatechange = function () {
switch(request.readyState) {
case 0:
// 未初期状態
console.log("Not initialized ... ");
break;
case 1:
// データ送信中
console.log("Sending data ... ");
break;
case 2:
// 応答待ち
console.log("Waiting for response ... ");
break;
// データ受信中
case 3:
console.log("Receiving of data ... ");
break;
case 4:
// データ受信完了
if (request.status == 200) {
var response_data = this.response;
if (key === '') {
console.log("Complete!!\n");
console.log(response_data);
callback(response_data);
} else {
console.log("Complete!!\n");
console.log(response_data[key]);
// コールバック
callback(response_data[key]);
}
} else {
console.log( 'Failed. HttpStatus: ' + request.statusText)
}
break;
}
};
// Httpリクエストに必要な情報
request.open(method, endpoint, true);
request.setRequestHeader('content-type', 'application/json');
request.responseType = 'json';
// Httpリクエストを送信(引数指定で特定の情報のみを送信)
request.send(parameters);
}
ハンドラーを登録し、随時処理中のステータスが出力するように更新し、consoleを開いたときのlogをわかりやすくしました。