Fetch APIによる非同期処理とは?
Fetch APIはブラウザに搭載された非同期処理をするための関数です。
fetch関数を用いることで、ブラウザのページを全て更新することなく
一部分だけを更新する非同期処理が実行できます
Laravelでは
Model
View
Controller
の3つに分けてコードを管理するため
fetchメソッドもMVCの流れに沿う必要があります
fetch関数は第一引数に指定したURLにhttp通信(リクエスト)を送信することで
Laravelのルーティングを経由しコントローラに記述したアクションを実行します
コントローラ側でデータベースの操作および情報を取得した処理を実行した後、
fetch関数に対して実行結果(レスポンス)を返します。
JavaScriptにはブラウザのHTMLを書き換えたり追記したりする機能があるため
必要に応じて現在表示されているブラウザのHTMLにレスポンスの内容を反映させます
つまり非同期で部分的にHTMLを書き換えることができます
scriptタグに直接記述する方法があります
function indexAll(){
// ここにfetch関数のコードを記述していきます
// 最後に関数を実行します
// functionを動かす条件として”ボタンを押した場合”などの条件がない場合は
// ブラウザが更新されるとコードが上から順に、つまりHTMLとjavascriptが読み込まれるため
// indexAllは自動で実行されることになります
indexAll();
fetchの基本構文
通常の書き方
fetchメソッドは通信が成功
したか、失敗
したかを結果として返します
結果を参照する場合はfetchメソッドのpromiseオブジェクト
を呼び出します
phpから受け取ったpromiseオブジェクト
をJavaScriptで利用するためにはJSONファイルに変換が必要です
後述のメソッドチェーン
を利用するとfetchから取得した結果をそのまま別のメソッドに渡すことができます。
fetch.js
function indexAll(){
fetch('URLを記述する第一引数') //(1)
.then((任意の変数名1) => {return 任意の変数名1.json()}) //(2)
.then((任意の変数名2) => { //(3)
//(4)
.catch(error => {
//(5)
alert("実行失敗");
alert(error);
//(1) コントローラーへ繋がるURLを記述することで
//(1) コントローラーへ「データベースの情報が欲しい」と"リクエスト"を送信します
//(1) コントローラーのアクションには「データベースの情報を操作する処理」を記述しておき
//(1) アクションを実行することでデータベースのテーブル情報を取得し結果をfetchに返します。
//(1) "fetch"の返り値は"Promise"と呼ばれるオブジェクト
//(1) "Promise"の中身は”通信成功”もしくは”通信失敗”という結果データが入っています
//(1) さらに"Promise"には"response"が格納されており
//(1) "response"はデータベースから取得したテーブルデータなどが代入されています
//(2) ドット ”.” によるメソッドチェーンを使うことでfetchの結果である"Promise"をインスタンス化して参照することができます
//(2) thenメソッドは通信が成功した場合の処理を実行することができます
// ※ catchメソッドは通信が失敗した場合の処理を実行することができます
//(2) "Promise"を参照し内部の"response"を引数として渡すことで
//(2) "response"を"jsonファイル"として解釈した結果を返します
//(3) jsonに変換した"response”を”任意の変数”に代入することで実行する処理の中で変数を利用できるようにします
//(3) 処理の内容は取得してきたテーブルのレコードをHTMLのタグで追加する処理を実行します
//(4) コントローラーとの通信が成功した場合に実行するコードを記述する
//(4) HTMLにタグを追加するコードを記述する
//(5) コントローラーとの通信が失敗した場合に実行するコードを記述する
//(5) エラーコードやエラーメッセージなどを記述する
基本構文の省略形(意味は同じになります)
処理が1行だけの場合{}
とreturn
は省略できます
fetch.js
fetch('URLを記述する第一引数') //(1)
.then((response) => response.json()) //(2)
.then((res) => {
// (3) 通信が成功した場合の実行したい処理を記述する
.catch(error => {
//(5)
alert("実行失敗");
alert(error);
参考サイト:https://www.sejuku.net/blog/52314
fetch() で通信が成功した場合のレスポンスを操作できます
ここでは通信が成功したため受け取ったレスポンスをjsonファイルに変換し
受け取ったレスポンスに存在するテーブルの情報をHTMLに反映させます
catchメソッドとは
fetch() で通信が失敗した場合のレスポンスを操作できます
alertでfetchの結果を確認すると、エラー内容が確認できます
JSONファイルとは
テキスト形式のファイルのことでJSONとはJavaScript Object Notation
の略で
ジェイソン
と呼ばれています。
JSONはJavaScriptで定義されているオブジェクト表記法の1つで
テキスト形式で表記されるため簡単にデータ交換ができます。
その可読性からJavaScriptに限らず主要なプログラム言語から利用されています。
メソッドチェーンとは
参考サイト:https://www.sejuku.net/blog/24962
メソッドの実行結果を変数などを代入する手間を省略し、
直接他のメソッドの引数
に代入後、次のメソッドを実行することができます。
JavaScriptではメソッドを「 .」(ドット)で連結するため
fetchメソッドやの後に.then
を実行しています
Fetch関数でテーブルの一覧を表示させる
fetch関数に利用するURLを設定する
まずはfetchの通信先を設定するためにルーティングを設定します。
これでfetchメソッドの第一引数に/show_all
を渡すことで
コントローラーのshowAll
が実行されます
web.php
Route::get('/', 'HomeController@index')->name('crud.index'); /* 初期ページ */
Route::get('/show_all', 'HomeController@showAll'); // 全表示アクション
全てのcompaniesテーブルの全てのレコードを取得する
値はid
name
price
をまとめた連想配列に格納する
完成した配列はjavascriptで扱えるようにjsonデータに変換してfetchに送信する
****Controller.php
public function showAll()
/* $companies = \DB::table('companies')->get(); */
$companies = Companies::get();
foreach($companies as $companie){
$companieList[] = array(
'id' => $companie->id,
'name' => $companie->name,
'price' => $companie->price
// echoで配列をjsonに変換しつつfetchへサーバー情報を送信する
echo json_encode($productList);
Eloquentとクエリビルダについて
参考先:https://qiita.com/Laravel-student/items/83475abb6d6acb3a177f
データベースを操作する方法にはEloquent(エロクエント)と
クエリビルダという手法がありますが、どちらでデータを取得しても
問題ありません
Eloquentの場合
// Companiesモデルを利用しデータを取得する方法です
$products = Companies::get();
クエリビルダの場合
//DBファザードを利用しデータを取得する方法です
$companies = \DB::table('companies')->get();
// forEach はphpの繰り返し処理です "res"に存在する配列の数だけ繰り返すことができます
// メソッドチェーンにより、"res"の値は"elm"に代入され、次からの処理はelmという連想配列を使うことができます
// resと区別するため繰り返し処理中では連想配列の値は"elm"という配列名に代入して利用していきます
// "elm"は"element"の略称です エレメント(要素)とは「HTMLタグ」で囲んだ情報の単位を示します
res.forEach(elm =>{
// ここにHTMLを追加する処理を記述します
//目的として、データベースから取得した情報(レスポンス)を使って、<tr>、<td>タグによるレコードを挿入します
//手段としては上述されている"index.braid.html"に存在する"result"という名前に設定したID属性の場所を取得し
//その下層にHTMLタグを挿入します
alert("実行成功");
.catch(error => {
// "error" は任意の変数名です 可読性を高めるためにエラーに関する変数名は"error"で統一します
alert("実行失敗");
alert(error);
// 関数を実行します
indexAll();
fetch.js
// 取得したレコードをeachで順次取り出す
res.forEach(elm =>{
// forEach は phpの繰り返し処理 resに存在する配列の数だけ繰り返します
// resと区別するため繰り返し処理中では連想配列の値は"elm"という配列名に代入して利用していきます
// "elm"は"element"の略称です エレメント(要素)とは「HTMLタグ」で囲んだ情報の単位を示します
var insertHTML = "<tr class=\"target\"><td>" + elm['id'] + "</td><td>" + elm['name'] + "</td><td>" + elm['price'] + "</td></tr>"
var result = document.getElementById("result");
result.insertAdjacentHTML('afterend', insertHTML);
//メソッドチェーンで"result"に含まれる結果を参照します
//insertAdjacentHTMLは指定したテキストを指定した場所に挿入することができます
//第一引数は場所,第二引数はテキストになります('afterend'= 要素自身の後ろ)
alert("実行成功");
.catch(error => {
// 取得したレコードをeachで順次取り出す
alert("実行失敗");
alert(error);
// 関数を実行します
indexAll();