JavaScript
Ajax
Rails5

[Rails]Ajaxを使ったチャット機能(エラー、バグ編)


はじめに

現在Ajaxを使ったチャット機能を開発していて、その中でも特に手を焼かせたエラーを紹介したいと思います。

今回はこのチャット機能の作り方ではなくて発生したエラー、バグをどのように解決したかを共有するものです。

簡単でそんなこともわからないのかと思われる方もおられるかもしれませんがそこはグッと堪えてください。

ちなみにこちらが開発中のチャットアプリです。

スクリーンショット 2019-03-10 17.49.22.png


1.送信すると[object Object]と表示される。

一通りの機能が完成したので試しにメッセージを送信してみました。

1回目は「あああああ」とテキストだけ。

2回目は画像だけを送信しました。

すると、、、

画像のようにテキストを送信してもイメージタグも一緒に送信され[object Object]と表示され、画像だけを送信しても[object Object]と表示されてしまいます。

スクリーンショット 2019-03-11 9.38.07.png


原因


・jbuilderの書き方が間違っていた。

そもそもjbuilderでの画像の書き方が間違っていました。

_message.html.hamlではimage_tag message.image.urlとなっているのに、jbuilderではmessage.imageとしか書いていなかったため上手く読み込まれなかったということです。


_message.html.haml

.message

.message--upper__info
.message--upper__info__user
= message.user.name
.message--upper__info__date
= message.created_at.strftime("%Y/%m/%d %H:%M")
.message--lower
- if message.content.present?
%p.message--lower__text
= message.content
= image_tag message.image.url, class: 'message--lower__info' if message.image.present?


create.json.jbuilder

json.image   @message.image

#これを以下のように治した。
json.image @message.image.url


これで[object Object]という表示は解消されるが次はnullと表示される。

これは以下で解決していく。


・デフォルトで画像が表示される設定になっていた。

メッセージ機能は画像もテキストも両方送ることができるが、現状だとテキストのみを送信しても画像が付いてくる。

これは変数を使って治す。

下の方にある

内にはデフォルトでテキストと画像が表示されるようになっている。

解決法としてはデフォルトで画像を表示させずに、条件分岐で「画像があったら変数imageに画像を送る。無かったら画像は表示させない」という風にしていく。


before

  function buildHTML(message) {

var html = `<div class="message">
<div class="message--upper__info">
<div class="message--upper__info__user">
${message.user_name}
</div>
<div class="message--upper__date">
${message.created_at}
</div>
</div>
<div class="message--lower">
<p class="message--lower__text">
${message.content}
</p>
${message.image}   #ここを${image}に変えるよ
</div>
</div>`

return html;
}


after

  function buildHTML(message) {

var image = ""
message.image ? image = `<img src="${message.image}">` : image = ""

var html = `<div class="message">
<div class="message--upper__info">
<div class="message--upper__info__user">
${message.user_name}
</div>
<div class="message--upper__date">
${message.created_at}
</div>
</div>
<div class="message--lower">
<p class="message--lower__text">
${message.content}
</p>
${image}
</div>
</div>`

return html;
}


これでテキストを送信したらテキストだけ表示。

画像を送信したら画像だけ表示が実現できた。


2.連続投稿できない

やっと問題が解決できたと思っていたら次は肝心な送信機能自体に問題があり、一度再読み込みしないと送信できない状態になっている。


原因

検証でformを見てみると

送信前

スクリーンショット 2019-03-11 10.06.50.png

送信後

スクリーンショット 2019-03-11 10.07.03.png

違いがわかりますか?

送信した後にdisabledという文字が追加されており、こいつが今回の原因。


解決策

とりあえず「disabled」。こいつが表示されないようにしていく。


message.js

$('#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)
$('#message_js').val('')

//////////////こいつも加える。↓
$('form')[0].reset();
////////////////

scroll();
})
.fail(function() {
alert('error');
})

//ここから
.always(() => {
$(".submit__btn").removeAttr("disabled");
});
//ここまでを追加して$(".submit__btn")は自身のsubmitボタンのidなりclass名で!


以上の2点を追加することで解決することができた。