はじめに
この記事では、片方がコメントを送信したら、もう片方の人はリロードしなくても、コメントが表示されるチャットアプリを作っていきたいと思います。
完成物
ソースコード:https://github.com/Alesion30/ChatApp
非同期通信とは
非同期通信とは、ネットワークなどでつながれているコンピュータ間で、送信者のデータ送信タイミングと受信者のデータ受信タイミングを合わせずに通信を行う通信方式のこと。
日常生活の例でいうとこんな感じ。
同期通信
非同期通信
同期通信の場合は、リクエストを送信したらリロードが入り、他の処理を受け付けなくなるが、非同期通信の場合は、リクエストを送信しても、リロードが入らず別の処理を送信することもできる。
方針
- APIを作る。(URLにアクセスしたら、jsonデータを返すやつ)
- JavaScriptで、APIを叩きjsonデータを取得する。
- ループ処理を用いてjsonデータを、bladeファイルに埋め込む。
APIを作る
HomeController.phpにjsonを返すgetData()という関数を定義する。
public function getData()
{
$comments = Comment::orderBy('created_at', 'desc')->get();
$json = ["comments" => $comments];
return response()->json($json);
}
web.phpに、getData()を登録する。
Route::get('/result/ajax', 'HomeController@getData');
http://localhost/ChatApp/public/result/ajax にアクセスすると、jsonデータが返ってくる。
ajaxを使って、jsonを取得する
ajaxを使えるようにするために、app.blade.phpのheadの部分でスクリプトを読み込む。
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
これはajaxの基本形である。dataTypeには、jsonだけでなく、csvやhtmlも指定できる。
$.ajax({
url: "result/ajax/",
dataType: "json",
success: data => {
// 成功時の処理
},
error: () => {
// エラー時の処理
}
})
public/jsフォルダにcomment.jsを新規作成する。5秒ごとに、jsonデータを取得している。
$(function() {
get_data();
});
function get_data() {
$.ajax({
url: "result/ajax/",
dataType: "json",
success: data => {
console.log(data);
},
error: () => {
alert("ajax Error");
}
});
setTimeout("get_data()", 5000);
}
app.blade.phpのbodyタグの一番下に、@yield('js')
を入れる。
<main class="py-4">
@yield('content')
</main>
</div>
@yield('js')
</body>
home.blade.phpの一番下で、comment.jsを読み込む。
@section('js')
<script src="{{ asset('js/comment.js') }}"></script>
@endsection
http://localhost/ChatApp/public/home にアクセスして、検証ツールを使うと、5秒ごとにjsonデータが送られてきていることがわかる。
comment.jsのsuccessの処理を以下のように書き換えてみる。
success: data => {
console.log(data.comments);
for (var i = 0; i < data.comments.length; i++) {
console.log(data.comments[i].name);
console.log(data.comments[i].comment);
}
},
ループ処理を用いてjsonデータを、bladeファイルに埋め込む。
home.blade.phpでコメントを表示している部分を書き換える。
<div class="chat-container row justify-content-center">
<div class="chat-area">
<div class="card">
<div class="card-header">Comment</div>
<div class="card-body chat-card">
<div id="comment-data"></div>
</div>
</div>
</div>
</div>
JavaScriptで、<div id="comment-data"></div>
の中にコメントを埋め込んでいく形になる。
comment.jsのsuccessの処理を以下のように書き換える。
success: data => {
$("#comment-data")
.find(".comment-visible")
.remove();
for (var i = 0; i < data.comments.length; i++) {
var html = `
<div class="media comment-visible">
<div class="media-body comment-body">
<div class="row">
<span class="comment-body-user" id="name">${data.comments[i].name}</span>
<span class="comment-body-time" id="created_at">${data.comments[i].created_at}</span>
</div>
<span class="comment-body-content" id="comment">${data.comments[i].comment}</span>
</div>
</div>
`;
$("#comment-data").append(html);
}
},
http://localhost/ChatApp/public/home にアクセスして、コメントを追加するとうまく反映している。