質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

1回答

1198閲覧

railsチャットアプリにおける非同期通信実装時に出会ったエラー(ページが遷移してしまう問題)の解決策をご教授頂きたいです。

ka234

総合スコア3

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2020/10/25 02:17

編集2020/10/25 08:12

解決したいこと

raisで実装中のチャットアプリにて、相互フォローユーザ間で作られた1対1のトークルームにおけるメッセージのやり取りを非同期通信にしたいと思い実装を行ったのですが、現状では下記の画像のようにメッセージ送信後、画面遷移が行われてしまいます。

①【url: rooms/[:id]のチャットページにて、メッセージを入力し、送信ボタンを押すと...】
イメージ説明

②【url: messagesのページへ移り、保存された情報が表示されてしまう。】
イメージ説明

記述したrubyのコード(messages_controller.rb)

ruby

1 def create 2 if Entry.where(user_id: current_user.id, room_id: params[:message][:room_id]).present? 3 message = Message.create(message_params) 4 render json:{ message: message } 5 else 6 flash[:alert] = "メッセージ送信に失敗しました。" 7 end 8 end 9 10 private 11 def message_params 12 params.require(:message).permit(:content, :user_id, :room_id).merge(user_id: current_user.id) 13 end

記述したJavaScriptコード(message.js)

javascript

1function chat() { 2 const submit = document.getElementById("submit"); 3 submit.addEventListener("click", (e) => { 4 5 e.preventDefault(); 6 const formData = new FormData(document.getElementById("form")); 7 const XHR = new XMLHttpRequest(); 8 XHR.open("POST", "/messages", true); 9 XHR.responseType = "json"; 10 XHR.send(formData); 11 XHR.onload = () => { 12 if (XHR.status != 200){ 13 alert(`Error ${XHR.status}: ${XHR.statusText}`); 14 return null; 15 } 16 const item = XHR.response.message; 17 const list = document.getElementById("list") 18 const formText = document.getElementById("content-message") 19 const HTML = ` 20 <div class="chat-box"> 21 <div class="chat-face"> 22 if (${message.user.avatar}.attached?){ 23 <img src="${message.user.avatar}", class="icon-image-mini"> 24 } 25 </div> 26 <div class="chat-message"><strong>${message.content}</strong><br> 27 l ${message.created_at} 28 </div> 29 </div> 30 `; 31 list.insertAdjacentHTML("afterend", HTML); 32 formText.value = ""; 33 }; 34 }); 35} 36 37window.addEventListener("load", chat);

記述したHTMLビューファイル

html

1<div class="messages", id="message"> 2 <div class="chat-header"> 3 <div class="left-button"> 4 <%= link_to '〇〇さんとのチャットルーム', root_path %> 5 </div> 6 <div class="room-exit"><%= link_to 'トップページに戻る', root_path %></div> 7 </div> 8 <% @entries.each do |e| %> 9 <div class="user-name"> 10 <strong> 11 <% if e.user.avatar.attached? %> 12 <%= image_tag e.user.avatar, class:"icon-image" %> 13 <% end %> 14 <a class="room-user-link" href="/users/<%= e.user.id %>"> 15 <%= e.user.name%>さん 16 </a> 17 </strong> 18 </div> 19 <% end %> 20 <hr> 21 <div class="chats"> 22 <div class="chat"> 23 <% if @messages.present? %> 24 <% @messages.each do |m| %> 25 <div class="chat-box"> 26 <div class="chat-face"> 27 <% if m.user.avatar.attached? %> 28 <%= image_tag m.user.avatar, class:"icon-image-mini" %> 29 <% end %> 30 </div> 31 <div class="chat-message"><strong><%= m.content %></strong><br> 32 <%= l m.created_at %> 33 </div> 34 </div> 35 <% end %> 36 <% end %> 37 <div id="list" ></div> 38 </div> 39 </div> 40</div> 41<div id="chat"> 42<span id="video-end">ビデオ通話を止める</span> 43 <chat /> 44</div> 45<%= javascript_pack_tag 'chat' %> 46<%= stylesheet_pack_tag 'chat' %> 47<div class="form"> 48 <%= form_for @message, id: "form", class: "post" do |f| %> 49 <div class="post-message"> 50 <%= f.text_field :content, placeholder: "メッセージを入力してください", size: 70, class:"form-text-field", id:"content-message" %> 51 <%= f.hidden_field :room_id, value: @room.id %> 52 <%= f.submit '送信', class:"form-submit", id: "submit" %> 53 <input type="button" value="ビデオ通話を始める", class="form-submit", id= "video-button"> 54 </div> 55 <% end %> 56</div>

生じているconsoleエラー

message.js:4 Uncaught TypeError: Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'. at HTMLInputElement.<anonymous> (message.js:4)

試したこと

DBには送信した内容が正しく保存されていたことから、通常のcreateアクションが働いてしまっているため、上記のような挙動になっているのかと思い、e.preventDefault();を追加しました。が、追加した場所が悪いのか挙動に変化はありませんでした。

また、messageの保存作業がmessageコントローラーのcreateアクションで行われているのに対して、保存したメッセージの表示場所をroomsコントローラーのindexのshowアクションに設定していることが原因かとも考えましたが、具体的な解決策は浮かびませんでした。

稚拙な質問で申し訳ありませんが、ご回答頂けると幸いです。

その他、補足情報

Mac OS Catalina 10.15.4
ruby 2.6系
rails 6.0系
を使っております。
また、message.jsファイルはapplication.jsに読み込み済みです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/10/25 02:28

ビューのHTMLはどのようになっていますか?
ka234

2020/10/25 06:27

コメントありがとうございます。ビューファイルの追記を行いました!!
guest

回答1

0

e.preventDefault()のタイミングがおかしいです。

e.preventDefault()XHR.onloadの中に入っていますので、クリックの際にはe.preventDefault()が呼ばれず、そのままフォームとしての送信が始まってしまいます(XHR.onloadで実行しても手遅れです)。

clickのハンドラ直下でe.preventDefault()を行うか、そもそもフォーム送信が行われないtype="button"のボタンを使うかをしましょう。

投稿2020/10/25 06:32

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ka234

2020/10/25 07:35 編集

ご回答ありがとうございます!clickのハンドラ直下でpreventDefaultを行う方法と、type=buttonにフォームを変更する方法それぞれ行ってみました。すると、画面遷移の問題は解決したのですが、ボタンを押してもメッセージが投稿されない問題が生じてしまいました。なおconsoleでは、下記のようなメッセージが表示されていました。重ね重ね申し訳ございませんが、想定される原因などご回答いただけますでしょうか? 【エラーメッセージの内容】 message.js:4 Uncaught TypeError: Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'. at HTMLInputElement.<anonymous> (message.js:4)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問