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

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

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

Sequel Proは、Mac OS X向けMySQLフロントエンドです。GUIからのMySQLの操作・管理が可能になります。強力なクエリ編集、多彩なエンコーディングオプションのサポートなど多くの機能を備えています。

Ruby

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

Ruby on Rails

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

JavaScript

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

1回答

1449閲覧

JavaScript・Ajaxを用いた非同期通信のチャット機能を実装したい

ro-ru_ke-to

総合スコア0

Sequel Pro

Sequel Proは、Mac OS X向けMySQLフロントエンドです。GUIからのMySQLの操作・管理が可能になります。強力なクエリ編集、多彩なエンコーディングオプションのサポートなど多くの機能を備えています。

Ruby

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

Ruby on Rails

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

JavaScript

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2021/07/20 06:12

前提・実現したいこと

①チャット機能において、JavaScript・Ajaxを使用した非同期通信を実装したいのですが、「チャットしたユーザー名のチャット画面における未定義」だと思われるエラー文が出ます(1度リロードすると送信した文章が表示されます)。
②また、仮にユーザー名を抜いた状態で文章(content)のみを非同期通信にて実装しようとしましたが、これはこれで出来ません(1度リロードしないと反映されません)。

①・②のいずれかだけでも大丈夫ですので、ご回答頂ければ幸いです。

発生している問題・エラーメッセージ

[コンソール] ① chat.js:3 Uncaught TypeError: Cannot read property 'nickname' of undefined at buildHTML (chat.js:3) at XMLHttpRequest.XHR.onload (chat.js:28) ※②に関するエラー文は出ませんでした

該当のソースコード

RubyonRails

1[routes.rb] 2 3Rails.application.routes.draw do 4 devise_for :users, controllers: { registrations: 'registrations' } 5 get 'chat/:id' => 'chats#show', as: 'chat' 6 get 'cats/index' 7 root to: "cats#index" 8 resources :cats, only: [:new, :create, :show, :edit, :update, :destroy] 9 resources :users, only: [:show] 10 resources :chats, only: [:create] 11end 12

RubyonRails

1 2[chats_controller.rb] 3 4class ChatsController < ApplicationController 5 before_action :authenticate_user!, only: [:show, :create] 6 def show 7 @user = User.find(params[:id]) 8 rooms = current_user.user_rooms.pluck(:room_id) 9 user_rooms = UserRoom.find_by(user_id: @user.id, room_id: rooms) 10 11 unless user_rooms.nil? 12 @room = user_rooms.room 13 else 14 @room = Room.new 15 @room.save 16 UserRoom.create(user_id: current_user.id, room_id: @room.id) 17 UserRoom.create(user_id: @user.id, room_id: @room.id) 18 end 19 @chats = @room.chats 20 @chat = Chat.new(room_id: @room.id) 21 end 22 def create 23 @chat = current_user.chats.new(chat_params) 24 @chat.save 25 render json:{ post: @chat } 26 end 27 28 private 29 def chat_params 30 params.require(:chat).permit(:content, :room_id) 31 end 32end

RubyonRails

1 2[chats/show.html.erb] 3 4<%= form_with model: @chat, id:"form" do |f| %> 5 <%= f.text_field :content, id: "content" %> 6 <%= f.hidden_field :room_id %> 7 <%= f.submit value: "送信する", class:"chat-btn", id: "submit" %> 8<% end %> 9 10<div id="list"> 11</div> 12<table class="chat-table"> 13 <thead> 14 <tr> 15 <td>投稿者名</td> 16 <td>投稿内容</td> 17 </tr> 18 </thead> 19<tbody> 20 <% @chats.each do |chat| %> 21 <tr> 22 <td><%= chat.user.nickname %></td> 23 <td><%= chat.content %></td> 24 </tr> 25 <% end %> 26</tbody> 27</table>

JavaScript

1 2[application.js] 3 4require("@rails/ujs").start() 5require("turbolinks").start() 6require("@rails/activestorage").start() 7require("channels") 8require("../chat") 9

JavaScript

1 2[chat.js] 3 4const buildHTML = (XHR) => { 5 const item = XHR.response.post; 6 const html = ` 7 <tr> 8 <td>${item.user.nickname}</td> 9 <td>${item.content}</td> 10 </tr>`; 11 return html; 12}; 13 14function post (){ 15 const submit = document.getElementById("submit"); 16 submit.addEventListener("click", (e) => { 17 e.preventDefault(); 18 const form = document.getElementById("form"); 19 const formData = new FormData(form); 20 const XHR = new XMLHttpRequest(); 21 XHR.open("POST", "/chats", true); 22 XHR.responseType = "json"; 23 XHR.send(formData); 24 XHR.onload = () => { 25 if (XHR.status != 200) { 26 alert(`Error ${XHR.status}: ${XHR.statusText}`); 27 return null; 28 }; 29 const list = document.getElementById("list"); 30 const formText = document.getElementById("content"); 31 list.insertAdjacentHTML("afterend", buildHTML(XHR)); 32 formText.value = ""; 33 }; 34 }); 35}; 36 37window.addEventListener('load', post);

試したこと

turbolinksに関しては、遷移前のlink_to内で、data: {"turbolinks"=>false}を記述しています。
また、エラー文について同様の記事を複数見かけましたが、具体的な解決方法が分かりませんでした。

補足情報(FW/ツールのバージョンなど)

ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin20]

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.5'

gem 'rails', '~> 6.0.0'

gem 'mysql2', '>= 0.4.4'

gem 'puma', '~> 3.11'

gem 'sass-rails', '~> 5'

gem 'webpacker', '> 4.0'
https://github.com/turbolinks/turbolinks
gem 'turbolinks', '
> 5'

gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
gem 'capistrano'
gem 'capistrano-rbenv'
gem 'capistrano-bundler'
gem 'capistrano-rails'
gem 'capistrano3-unicorn'
gem 'rspec-rails'
gem 'factory_bot_rails'
gem 'faker'
end

group :development do
gem 'rubocop', require: false

gem 'web-console', '>= 3.3.0'
gem 'listen', '>= 3.0.5', '< 3.2'

gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
gem 'capybara', '>= 2.15'
gem 'selenium-webdriver'
gem 'webdrivers'
end

group :production do
gem 'unicorn', '5.4.1'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
gem 'devise'
gem 'pry-rails'
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
gem 'active_hash'

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

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

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

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

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

guest

回答1

0

xhrでは煩雑で無理が多いと思います
よほど古いブラウザに対応する必要がないならfetchでの実装がベターです

投稿2021/07/20 06:34

yambejp

総合スコア114839

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

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

ro-ru_ke-to

2021/07/20 07:34

ご回答ありがとうございます。fetchでの実装はやったことがないので、色々調べて試してみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問