LoginSignup
3
3

More than 3 years have passed since last update.

非同期通信でメッセージ送信する方法について

Posted at

非同期通信の実装においての理解をアウトプットしてみた。

非同期通信でメッセージ送信とは?

身近な例で言えば、LINEでメッセージを送信した際、送信したメッセージが画面の下にスクロールする動作がそれに当たる。

実装手順

1.フォームが送信されたら、イベントが発火するようにする
2.イベントが発火したときにAjaxを使用して、messages#createが動くようにする
3.messages#createでメッセージを保存し、respond_toを使用してHTMLとJSONの場合で処理を分ける
4.jbuilderを使用して、作成したメッセージをJSON形式で返す
5.返ってきたJSONをdoneメソッドで受取る
6.doneメソッドで受取り、HTMLを作成する
7.作成したHTMLをメッセージ画面の一番下に追加し、その分メッセージ画面を下にスクロールさせる
8.非同期に失敗した場合の処理も準備する
9.完成ソースコード

1.フォームが送信されたら、イベントが発火するようにする


$("#new_message").on('submit', function(e) {
      e.preventDefault();
      var formData = new FormData(this);
      var url = $(this).attr('action');
})

new_message であるフォームが送信されたら、イベントが発火する。

2.イベントが発火したときにAjaxを使用して、messages#createが動くようにする


$.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
      })

以上のように、ajax通信を行って、」コントローラのcreateアクションを動かす。

3.messages#createでメッセージを保存し、respond_toを使用してHTMLとJSONの場合で処理を分ける

messages_controller.rb


def create
    @message = @group.messages.new(message_params)
    if @message.save
        respond_to do |format|
            format.html {redirect_to group_messages_path(@group), notice: 'メッセージが送信されました'}
            format.json
        end
    else
        @message = @group.message.includes(:user)
        flash.now[:alert] = 'メッセージを入力してください'
        render :index
    end
end

以上のように、respond_to do |format| を使い、コントローラーのcreateアクション内で、formatがHTMLの時とjsonの時との処理を分ける。

4.jbuilderを使用して、作成したメッセージをJSON形式で返す

create.json.jbuilder


json.user_name    @message.user.name
json.content    @message.content
json.time    @message.created_at
json.id    @message.id

5.返ってきたJSONをdoneメソッドで受取る


      .done(function(data){
        var html = buildHTML(data);
        $('.messages').append(html);
        $('.form__message').val('');
        $('.form__submit').prop('disabled', false);
        $('.messages').animate({ scrollTop: $('.messages')[0].scrollHeight});
      })
      .fail(function(){
        alert('error')
        $('.form__submit').prop('disabled', false);

6.doneメソッドで受け取ったHTMLを作成する


$(function() {
  function buildHTML(message){
  var html = `<div class="message">
                <div class="upper-message">
                    <div class="upper-message__user-name">
                        ${ message.user_name }
                    </div>
                    <div class="upper-message__date">
                        ${ message.time }
                    </div>
                </div>
                <div class="lower-message">
                    <p class="lower-message__content">
                        ${ message.content }
                    </p>
                </div>
             </div>`
      return html; 
  }
    })
  })
})

7.作成したHTMLをメッセージ画面の一番下に追加し、その分メッセージ画面を下にスクロールさせる


 .done(function(data){
        var html = buildHTML(data);
        $('.messages').append(html);
        $('.form__message').val('');
        $('.form__submit').prop('disabled', false);
        $('.messages').animate({ scrollTop: $('.messages')[0].scrollHeight});
      })

スクロールさせる時は、animateとscrollHeightのメソッドが必要となる

8.非同期に失敗した場合の処理


.fail(function(){
        alert('error')
        $('.form__submit').prop('disabled', false);

連続でメッセージを送信しようとすると、エラーメッセージがアラートされる

9.完成ソースコード


$(function() {
  function buildHTML(message){
  var html = `<div class="message">
                <div class="upper-message">
                    <div class="upper-message__user-name">
                        ${ message.user_name }
                    </div>
                    <div class="upper-message__date">
                        ${ message.time }
                    </div>
                </div>
                <div class="lower-message">
                    <p class="lower-message__content">
                        ${ message.content }
                    </p>
                </div>
             </div>`
      return html; 
  }

  $("#new_message").on('submit', function(e) {
      e.preventDefault();
      var formData = new FormData(this);
      var url = $(this).attr('action');
      $.ajax({
      url: url,
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
      })

      .done(function(data){
        var html = buildHTML(data);
        $('.messages').append(html);
        $('.form__message').val('');
        $('.form__submit').prop('disabled', false);
        $('.messages').animate({ scrollTop: $('.messages')[0].scrollHeight});
      })
      .fail(function(){
        alert('error')
        $('.form__submit').prop('disabled', false);
    })
  })
})

以上、ざっくりとした解説でした。細かいコードの意味までは、まだ全然理解できていないので、どなたかご指摘いただけると助かります。

以上

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3