【詳しく解説】非同期通信の手順を作成したアプリで振り返る

プログラミング

こんにちは

この記事はプログラミングの知識を記録しておく目的で作成しています。

ご興味のある方は是非ご覧ください。

 

今回のお題は、

非同期通信の実装について

 

実装:非同期通信

そもそもどんなことだったかを知っておきましょう。

 

非同期通信とは?

送信フォームデータを送信するために送信ボタンを押した際、
ページがリロードされなくても情報が反映される。

 

例えばこんな様子。
sendボタンでカラーの値を保存して上左端に新しくカラーパネルを追加しています。

※写っていませんがリロードのマークもこれで動いていません。

Image from Gyazo

✔︎その他にも例えば…
・タスク管理アプリ:テキストフォームからタスクを追加→ページがリロードせず追加が表示される

✔︎非同期通信の実装目的は?
ページ遷移せずに一部だけ更新することで、
素早く更新でき、ユーザーが使いやすくなる。

 

 

今回実装する際の前提事項

✔︎Ruby、Ruby on Rails
✔︎JavaScript、jQuery
✔︎非同期通信とは?で出てきた例を実装する
 →イベント(フォーム送信)の発火をきっかけに、データが保存されてカラー情報が表示される。
✔︎VScode、HTML、HAML、SCSS

 

 

非同期通信の実装までの手順を把握して流れを掴む

それではどのように実装していくのか
タスクとして洗い出してみます。
なんとなく、どのような作業がなのか思い出せるようになるといいですね。

 

①JavaScriptとそのライブラリのjQueryを使用する準備をする。

 ✔︎jQueryを導入する
  →「yarn」インストールする
  →Gemを記述

 ✔︎JavaScriptのファイルを読み込む準備をする。
  →JavaScriptファイルを作るためのディレクトリを作成
  →そのディレクトリにJavaScriptのファイルを作成

 ✔︎ビューファイルにJavaScriptのファイルを呼び出せる記述
  →application.html.hamlにJavaScriptを呼び出す記述

私が作成しているアプリのapplication.html.haml
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title VisualMusic
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application'
%body
= yield

 ✔︎application.jsのファイルを呼び出せるようにする。

 ✔︎jQueryを使えるようにrequire rails-ujs」を記述。

 ✔︎application.js直下のファイルを読み込めるようにapplication.jsに記述する。

 ✔︎jQueryが動くか確認する
  →console.logを使用

 

 

②フォームが送信されたら発火するようにする。

 ✔︎フォームにイベントをセット
  →from要素を$( )で取得

 ✔︎デフォルトのフォームを送信する通信により画面遷移するのを阻止
  →e.preventDefault( )

 ✔︎デフォルトを阻止したらJSファイルでコンソールを使用して確認

 ✔︎ファーム送信(イベント発火)した時、Songcolors#createが動くようにする
  →FromDataの取得
  →Ajaxでデータを送りたいアクションのパスを記述
  →Ajax関数のオプションを設定

 

 

③Songcolors#createでメッセージを保存、 respond_toでHTMLで返す時とJSONで返す時の処理を分ける。

 ✔︎非同期通信でカラーのデータが保存されているか確認
  →保存した時ターミナルで「JSON」「COMMIT」になっているか確認。

 ✔︎respond_toで処理を分ける。JSONで返す。

私が作成しているアプリのsongcolors_controller.rbのcreateアクションの部分
def create
  @songcolor = Songcolor.create(color: params[:color], song_id: params[:song_id])
    respond_to do |format|
    format.json
  end
end

 

 

 ④jbuilderで保存したデータをJSON形式で返す。

 ✔︎respond_toで分けたのでjbuilderでデータを作成して返す
  →create.json.jbuilderを作成して必要なテーブルの情報を渡す。

私が作成しているアプリのapp/wives/songcolors/create.json.jbuilder
json.color @songcolor.color
・jbuilderは左がキー・右がバリューのようなハッシュの形になっている。
・例えば上記の例だと、json.colorがkeyで、@songcolor.colorがvalueとなる。

 

 ✔︎ターミナルのログでcreate.json.jbuilderが読み込まれているか確認。
  →Rendered songcolors/create.json.jbuilderという記載

 ✔︎binding.pry受け取った値を確認。

 

 

⑤返ってきたJSONをdoneメソッドで受け取り、 HTMLで見た目の変更(追加)部分を作成する。

 ✔︎HTMLを作成する。
  →function buildHTML(songcolors){…省略…return html }

 ✔︎値がdoneで引数として受け取れているかどうかconsole.logで確認もできたらする。
  →.done(function(data){let html = buildHTML(data);で受け取れているか。

 

 

⑥作成したHTMLを画面のカラーパネル左端の一番上に追加する。

 ✔︎.prepend指定した要素の最初に、引数で指定した内容を追加。

 

 

⑦連続で送信ボタンを押せるようにする。

 ✔︎disabled仕様でその様に設定されている「一度投稿をすると送信ボタンが押せなくなってしまう」設定を解除する。

 

 

⑧非同期に失敗した場合の処理をする。

 ✔︎エラーのアラートを出す。

 

これで完了です!!

 

 

詳しい解説を見ながら実装したい人はする

✔︎各項目のリンク先は詳細な解説

「非同期通信の実装までの手順を把握しよう」の各項目に詳しい解説のurlに飛べるようにしているので非同期通信を実装するヒントにすると実装しやすいますのでいので見てみてください。

また、「✔︎マーク」の前にチェックボックス「」をつけていますので、よろしければどこの項目を実装しているのかわかりやすいようにチェックして使用してみてください。ただページを更新すると消えてしまうのでご注意ください。

 

 

 

 

コードを記述したファイルの全体を見てみる

筆者の書いたコードなので、
記録ようです。
全体が見えると部分でコードを見るのとまた違って見えるので公開します。

 

私が作成しているアプリのGemfile(jQueryの導入)
//上は省略

gem 'devise'
#ユーザー管理のため


gem 'jquery-rails'


gem 'pry-rails'
#binding.pry使えるgem

 

私が作成しているアプリのapplication.html.haml
!!!
%html
%head
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
%title VisualMusic
= csrf_meta_tags
= csp_meta_tag
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'
= javascript_include_tag 'application'
%body
= yield

※説明時「①JavaScriptとそのライブラリのjQueryを使用する準備をする。」に載せているコードと同じです。

 

私が作成しているアプリのapp/assets/config/manifest.js(JavaScriptを読み込む)
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css

 

私が作成しているアプリのapp/assets/javascripts/application.js(jQueryを使えるように)
//= require jquery
//= require rails-ujs
//= require_tree .

 

私が作成しているアプリのapp/assets/javascripts/songcolor.jp
$(function() {
  function buildHTML(songcolor){
    let html =
      `<li class="color-box" style="background-color:${songcolor.color}"></li>`
    return html;
  };
  $('.js-form').on('submit', function(e) {
    e.preventDefault()
    let formData = new FormData(this);
    let url = $(this).attr('action');
    $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
    })
    .done(function(data){
      let html = buildHTML(data);
      $('.colorForm__submit').prop('disabled', false) 
      $('.left-box__colors-fild').prepend(html);
    })
    .fail(function() {
      alert('error');
    });
  });
});

 

私が作成しているアプリのapp/controllers/songcolors_controller.rb
class SongcolorsController < ApplicationController
  before_action :set_song

  def index
    @songcolor = Songcolor.new
    @songcolors = Songcolor.where(song_id: @song).order("created_at DESC")
  end

  def new
  end

  def create
    @songcolor = Songcolor.create(color: params[:color], song_id: params[:song_id])
    respond_to do |format|
      format.json
    end
  end

  private

  def songcolor_params
    params.permit(:color)
  end

  def set_song
    @song = Song.find(params[:song_id])
  end
end

 

私が作成しているアプリのapp/viwes/songcolors/create.json.jbuilder
json.color @songcolor.color

 

 

 

 

参考ページ

解説リンク先Qiita
 *jQueryの導入(HTML)
 *API(非同期通信を実装する場合)
 *JavaScriptのライブラリJQueryでイベント発火・Ajax(非同期通信を実装する場合)

From Dataについて

タイトルとURLをコピーしました