280日目 jQueryを使ったAjaxでイベント駆動型非同期処理を作ってみる　社畜ママ

こんにちは、社畜ママです！

先日、非同期処理・同期処理について理解したので、今回はAjaxを使って実際に非同期処理の動きを確認したいと思います。

今回はAjaxの説明と実際に動くコードを紹介します。

もしも同期処理・非同期処理についてあまり知らないかも、という方はぜひこちらの記事を参考にしてください。
https://qiita.com/QiiTaro_/items/3ae7dedf630db0b4187b

## Ajaxとは
Ajax（エイジャックス）は、"Asynchronous JavaScript and XML" の略で、JavaScriptを使ってウェブページがサーバーと非同期通信を行い、ページ全体をリロードせずに必要なデータだけを取得・送信できる技術です。

簡単に言うと、Ajaxを使えば「画面全体を更新せずに、特定のデータや部分だけを動的に更新する」ことができます。

## Ajaxの基本的な動作フロー
1.ブラウザ（クライアント）からリクエスト送信
ユーザーが操作を行うと、JavaScriptがサーバーにデータをリクエストします。

2.サーバーでリクエストを処理
サーバーは必要なデータを計算・取得し、クライアントにレスポンスを返します。

3.クライアントでレスポンスを処理
クライアントは受け取ったデータを解析し、ページの特定部分を更新します。

## Ajaxのサンプルコード
```javascript:jQuery
$.ajax({
    url: "/getData.php",
    type: "POST",
    data: {
       name: name,
    },
    dataType: "json",
    success: function (response) {
        // 処理が成功した時の処理をここに記述
    },
    error: function (xhr) {
        // エラーが発生した時の処理をここに記述
    console.log("エラーが発生しました: " + xhr.statusText);
    },
});
```

## Ajaxリクエストを送信するオプション
サーバへ送信するリクエストの設定について、少し詳しく見ていきます。
設定内容については、実際に開発した時どんな設定にしたかを主に記載しています。

<table>
  <caption></caption>
  <thead>
    <tr>
      <th>キー</th> <th>値</th> <th>設定内容</th>
    </tr>
  </thead>
  <tr>
    <td> url </td>
    <td>Ajaxリクエストを送信するURLを指定します。</td>
    <td>データの処理をするパスを指定します。データはこのパスに渡ります。Ajax通信用のパスを用意する必要があるので注意が必要です。</td>
  </tr>
  <tr>
    <td> type </td>
    <td>リクエストのタイプ("POST"または"GET")を指定します。</td>
    <td>データを取得するだけなので基本的にGETでよいとのこと。POSTは大容量のデータのやりとりに向いているようです。</td>
  </tr>
  <tr>
    <td> data </td>
    <td>サーバーへ送信するデータです。</td>
    <td>dataは{キー: 値}で渡すことができます。私はどちらも同じ名前にして混乱しないようにしています。</td>
  </tr>
  <tr>
    <td> datatype </td>
    <td>サーバから返ってくるデータの型を指定します(json, xml, htmlなど)。</td>
    <td>jsonが主流だそうです。データをやり取りするための軽量なフォーマットなので、Ajaxの処理に向いています。</td>
  </tr>
  <tr>
    <td> success </td>
    <td>リクエストが成功した際に呼び出される関数を指定します。</td>
    <td>urlで処理されたデータが返ってきたときの処理を記述します。引数(responce)にデータがわたってくるのでそれを使って画面の一部を更新します。</td>
  </tr>
  <tr>
    <td> error </td>
    <td>リクエストが失敗すると呼び出される関数です。</td>
    <td>何かしらエラーになり、urlからデータがわたってこなかったときの処理を記述します。</td>
  </tr>
  <tr>
    <td> beforeSend </td>
    <td>送信される直前にjqXHR(jQuery1.4.xではXMLHTTPRequest)オブジェクトの変更が可能な、コールバック関数です。</td>
    <td>使われる場面は限られますが、successの前にこの処理を入れてローディングの処理を入れることができます。</td>
  </tr>
  <tr>
    <td> complete </td>
    <td>リクエストが完了した際に呼び出される関数です。</td>
    <td>beforeSendと似ていますが、successやerrorの後に走る処理を書くことができます。ローディングが終わる処理を入れるのに適しています。</td>
  </tr>
</table>

他にもたくさんオプションがあります。
気になる方はこちらから確認できます↓
https://js.studio-kingdom.com/jquery/ajax/ajax

## jQueryでAjaxを実装してみよう
Ajaxについてなんとなくわかったところで、実際にコードを書いてみます。

Ajaxで処理できるものは多岐にわたりますが、その中でも「イベント駆動型非同期処理」という処理を実装していきます。
イベント駆動型非同期処理とは、プログラムが発生した「イベント」を検知し、それに応じて特定の処理（コールバック関数など）を非同期で実行する仕組みのことです。

例えば以下のような流れの処理があります。

①名前を選択
②選んだ名前に合わせて年齢・都道府県・電話番号を出力

今回はこの処理を実装したいと思います。

## 開発環境
バックエンド：laravel 11
フロントエンド：JavaScript(jQuery)
データベース：MySQL

AjaxはJavaScriptを使って実装します。

データベースやバックエンドの環境はお好みで問題ありませんが、私はlaravel(PHP)を業務で使用しているので、バックエンドはlaravelで記述していきます。dockerで環境構築しました。

また、今回はjQueryというJavaScriptのフレームワークを使用するので、そちらの準備をします。

## jQueryを使用できるように設定する
jQueryのインストール方法についてはいくつか方法がありますが、今回はnpmでインストールします。

dockerのコンテナ内に入って以下のコマンドを打ってjQueryをインストールします。
```bash:bash
npm install jquery
```
resources/js/app.js でjQueryをインポートします。

```javascript:app.js
import $ from 'jquery';
window.$ = window.jQuery = $;
```

welcome.blade.phpに以下のスクリプトタグを追加します。
```html:welcome.blade.php
<head>
    <script src="{{ mix('/js/app.js') }}"></script>
</head>
```
これでjQueryを使用する準備が完了しました。

## データを用意する
MySQLにデータを設定していきます。
例として以下のような3人分のデータを作成しました。

<table>
    <thead>
        <tr>
          <th>id</th> <th>name</th> <th>age</th> <th>live</th> <th>phone_number</th>
        </tr>
    </thead>
    <tr>
        <td>1</td>
        <td>太郎</td>
        <td>40</td>
        <td>鹿児島県</td>
        <td>080XXXXXXXX</td>
      </tr>
      <tr>
        <td>2</td>
        <td>ジロー</td>
        <td>30</td>
        <td>宮崎県</td>
        <td>080YYYYYYYY</td>
      </tr>
      <tr>
        <td>3</td>
        <td>さぶろう</td>
        <td>20</td>
        <td>熊本県</td>
        <td>080ZZZZZZZZ</td>
      </tr>
</table>

「太郎」さんを選んだら、「40」、「鹿児島県」、「080XXXXXXXX」というデータが画面上に出力されるようにしていきます。

## 実装する

### MySQLにデータを追加する
MySQLに新しいテーブル「user_data」を作成します。
通常はマイグレーションファイルを作成するのですが、今回は簡単に実装したいのでMySQL Workbenchを使って追加します。こちらからインストールできます。
https://www.mysql.com/jp/products/workbench/

次にlaravelの/app/ModelsフォルダにUserData.phpを追加してMySQLと連携させます。
UserData.phpは以下のように記述します。
```php:UserData.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class UserData extends Model
{
    protected $fillable = [
        'name', 
        'age',
        'live',
        'phone_number',
    ];
}
```

### 画面の表示
画面の表示は以下のコードで行います。
とりあえず画面に出したいので、laravelの方は/resorces/views/welcome.blade.phpというファイルに以下のコードを記述します。
```html:welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        @vite([
            'resources/css/app.css',
            'resources/js/app.js',
            'resources/js/getUserData.js'
        ])
    </head>
    <body class="font-sans antialiased dark:bg-black dark:text-white/50">
        <div>
            <p>名前</p>
            <select name="name">
                <option value="">-</option>
                <option value="太郎">太郎</option>
                <option value="ジロー">ジロー</option>
                <option value="さぶろう">さぶろう</option>
            </select>
        </div>
        <div id="printData"></div>
    </body>
</html>

```

### Ajaxの処理
続いて、jsファイルを作ってAjaxの処理を記述します。
laravelの方はresorces/jsの中にファイルを作ります。私は「getUserData.js」という名前で作りました。
```javascript:getUserData.js
document.addEventListener("DOMContentLoaded", function () {
    $("#name").on("change", function () {
        let name = $(this).val();

        const printUserData = function (data) {
            const printData = document.getElementById("printData");

            // 既存のデータをクリア
            printData.innerHTML = "";

            // 新しいデータを挿入
            printData.innerHTML = `
                <p>年齢: ${data.age}</p>
                <p>住所: ${data.live}</p>
                <p>電話番号: ${data.phone_number}</p>
            `;
        };

        $.ajax({
            url: "{{ route('getUserData') }}",
            type: "GET",
            data: {
                name: name,
            },
            success: function (response) {
                if (response) {
                    printUserData(response);
                } else {
                    console.log("データが見つかりません");
                }
            },
            error: function (xhr) {
                console.log("エラーが発生しました: " + xhr.statusText);
            },
        });
    });
});

```

### バックエンドの処理
Ajaxで受け取ったnameというデータとDBを紐づけて「年齢・住所・電話番号」のデータをAjaxに返します。
バックエンド側の処理なのでlaravelで記述します。
app/Http/ControllersにUserController.phpというファイルを作り、以下のコードを記述します。
```php:UserController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request; // Request クラスをインポート
use App\Models\UserData; // UserData モデルをインポート

class UserController extends Controller
{
    // Ajax 通信用メソッド
    public function getUserData(Request $request) 
    {    
        // name の値をリクエストから取得
        $name = $request->input('name');

        // データを取得
        $data = UserData::where('name', $name)
            ->get(); 

        // JSON 形式でデータを返す
        return response()->json($data);
    }
}

```

最後にAjax通信がUserController.phpに通るようにパスを設定します。
routes/web.phpでパスの設定ができるので、以下のコードを追加します。
```php:web.php
Route::get('/getUserData', [UserController::class, 'getUserData'])
    ->name('getUserData');
```

全体としてこのようになればOKです。
```php:web.php
<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;

// ルート: トップページ (welcome.blade.php を表示)
Route::get('/', function () {
    return view('welcome');
});

// Ajax 用ルート: ユーザーデータを取得する処理
Route::get('/getUserData', [UserController::class, 'getUserData'])
    ->name('getUserData');

```

これで実装は完了です。

## おわりに
今回はAjaxを使った非同期処理を実装してみました。
画面上では数行の動きですが、記述する箇所が多く少し難しいですね。

Ajaxは複数のファイルに記述するので、どこになにを書いたかの把握が少し複雑に感じますが、リロードせずに画面の一部を更新させる処理はwebサービスの開発では必須なので、今のうちにしっかり理解してスムーズに実装を進められるようになりたいです。

今回は以上です。
また次回よろしくお願いいたします。