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

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

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

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Q&A

解決済

1回答

1625閲覧

Vue.js 投稿を非同期に

Meitoku

総合スコア44

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

0グッド

0クリップ

投稿2021/03/08 11:46

編集2021/03/19 12:22

フォームイメージ
イメージ説明
Vue.jsでモーダルウィンドウで投稿フォームを表示してコメントを投稿できる仕組みにしています
投稿はできるのですがリロードしないとコメントができないようになってしまいます
どのようにすれば非同期で表示できるのでしょうか?

<template> <div class="tweet-comment"> <div v-for="e in text" :key="e.id"> {{e.comment}} </div> <modal name="comment-modal"> <form @submit.prevent="createComment"> <div v-if="errors.length != 0"> <ul v-for="e in errors" :key="e"> <li><font color="red">{{ e }}</font></li> </ul> </div> <div class="tweet-comment_form"> <input v-model="comment.text" type="text"> </div> <button type="submit" @click="registerModal">投稿する</button> </form> </modal> <button class="btn btn-primary my-2" @click="showModal(); resetForm()">コメント投稿</button> </div> </template> <script> import axios from 'axios' export default { data() { return { comment: { text: '' }, text: [], errors: '' } }, mounted() { this.fetchComments() }, methods: { createComment: function() { axios .post(`/api/v1/tweets/${this.$route.params.id}/comments`,this.comment) .then(response => { let e = response.data; }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); }, fetchComments() { axios .get(`/api/v1/tweets/${this.$route.params.id}/comments.json`) .then(response => { this.text = response.data }) }, showModal(){ this.$modal.show('comment-modal'); }, registerModal(){ this.$modal.hide('comment-modal'); }, resetForm(){ this.comment.text = ''; }, } } </script>

###追記
Railsと組み合わせてコメント機能を作っています
コントローラーでデータベースからjson形式でデータを取得しています

class Api::V1::CommentsController < ApiController # ActiveRecordのレコードが見つからなければ404 not foundを応答する rescue_from ActiveRecord::RecordNotFound, with: :render_status_404 def index @comments = Comment.where(tweet_id: params[:tweet_id]) render 'index', formats: 'json', handlers: 'jbuilder' end def create comment = Comment.new(comment_params) if comment.save render json: comment,status: :created else render json: { errors: comment.errors.full_messages }, status: :unprocessable_entity end end private def comment_params params.require(:comment).permit(:text).merge(user_id: current_user.id,tweet_id: params[:tweet_id]) end end

####Vue

<div class="comment-content_tweet"> <div id="comments_area"> <div v-for="e in text" :key="e.id"> {{e.comment}} </div> </div> <div class="comment-form"> <form @submit.prevent="createComment"> <div v-if="errors.length != 0"> <ul v-for="e in errors" :key="e"> <li><font color="red">{{ e }}</font></li> </ul> </div> <div class="tweet-comment_form"> <textarea v-model="comment.text" type="text"></textarea> </div> <button type="submit" class="game_record" >投稿する</button> </form> </div> </div> </div> </div> </template> <script> <script> import axios from 'axios' data() { return { comment: { text: '' }, errors: '' } }, mounted() { this.fetchTweets() this.fetchComments() }, methods: { fetchComments() { axios .get(`/api/v1/tweets/${this.$route.params.id}/comments.json`) .then(response => { this.text = response.data }) }, createComment: function() { axios .post(`/api/v1/tweets/${this.$route.params.id}/comments`,this.comment) .then(response => { let e = response.data; this.fetchComments() }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); } } } </script>

####解決

data() { return { comment: "", text: "", errors: '' } }, mounted() { this.fetchComments() }, methods: { //コメント fetchComments() { axios .get(`/api/v1/tweets/${this.$route.params.id}/comments`) .then(response => { this.comment = response.data }) }, createComment: function() { axios .post(`/api/v1/tweets/${this.$route.params.id}/comments`,{text: this.text}) .then(response => { // this.text = response.data; this.fetchComments() }) .catch(error => { console.error(error); if (error.response.data && error.response.data.errors) { this.errors = error.response.data.errors; } }); }

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

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

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

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

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

guest

回答1

0

ベストアンサー

問題と解決案

裏側の仕組みがご質問から分からないのでなんとも言えないところはありますが、
添付いただいているコードから推測するに投稿してからそのデータをコメントの表示に反映するロジックがないことが主な原因のように見えます。
createComment後に投稿したデータを含む最新のデータに更新するために、createCommentthen句でfetchCommentsを実行するなどすればthis.textに最新のデータが反映されてコメントが表示されるのではないかと推測したのですがいかがでしょうか?

こちら的外れでしたら、具体的にどのようにコメントを記録/取得しているか含め詳細をお伝えいただかないと回答が難しそうです。

以上ご確認をよろしくおねがいします!

投稿2021/03/17 14:56

marasonPD

総合スコア168

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

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

Meitoku

2021/03/18 11:48

ご回答ありがとうございます! 変化なしです 投稿ボタンを押すと、入力した文字が消えないまま固まってしまいます
marasonPD

2021/03/18 15:18

変化なしでしたか…。 試していただいた後のコードと、もしその上で何かエラーが発生していたらその内容など共有していただけますか?
Meitoku

2021/03/18 15:33

追記しました よろしくお願いいたします
marasonPD

2021/03/18 15:41

ありがとうございます。 「TypeError: Cannot read property 'url' of undefined」とのことなので、undefinedな変数のurlプロパティを参照しようとして発生したエラーですね。 気になるのは「url」を参照しようとするコードが現在見せていただいているコードの中に無いことです。 別のコンポーネントなどでそういった箇所はありますか? また、エラーを見る限り「TweetShowPage」コンポーネントがエラーの発生箇所のようですが、現在質問文に記載されているのが「TweetShowPage」コンポーネントでしょうか?
Meitoku

2021/03/18 15:58

はい、記載しているのがTweetShowPageになります urlですか・・参照している箇所はなかったような気がしますが・・
marasonPD

2021/03/18 16:12

うーん、エラーが発生している箇所を見れないことには何ともですね…。 現状お伝えできるのは回答にも書いた通り、投稿後にそのデータをフェッチするなどのロジックが無さそうなので、それが出来るようなロジックの追加が必要だというようなざっくりしたものになりそうです。 現状直面したエラーに関してはChromeで確認されているなら、添付いただいた 「[Vue warn]: Error in render: TypeError: Cannot read property 'url' of undefined」 のようなエラーに続いて単に「TypeError: Cannot read property 'url' of undefined」... ともう1つエラーが続いていたりしないでしょうか? それがあればそのエラーの詳細部分にエラーの発生したファイルやコードの位置に飛べるリンクのような物があるかなと思うのですが、そこから原因箇所を辿れそうにないでしょうか?
Meitoku

2021/03/19 11:14

ありがとうございます TypeError: Cannot read property 'url' of undefinedは画像取得のエラーでした コメント機能とは直接関係なかったみたいです コメント投稿後はエラーはcatchしませんが思い通りの動きになりません thenの後にthis.fetchComments()を記述しているのですが、それではダメなのでしょうか? fetchCommentsは動いてるみたいですが非同期で変わりません・・
marasonPD

2021/03/19 11:45

問題がどこなのか調べてみましょう。 > fetchCommentsは動いてるみたいですが非同期で変わりません・・ 動いているのは確かでしょうか?仮に確実に確認されたわけではなければ、下記など試してみてください。 1. fetchCommentsのaxios...の前にconsole.log('check')を仕込んで、そもそもfetchCommentsが動いているか確認する 2. fetchCommentsのthen句にconsole.log(response.data)を仕込んで望ましいデータが返って来ているか確認する
Meitoku

2021/03/19 12:21

ありがとうございます!できました dataの扱いが曖昧になっていました railsへ送信用のtext  fetchCommentsでデータ受け取り用のcommentを定義して thenでthis.fetchComments()をすれば非同期でできました! 言葉で説明するのは難しいのでコードを貼っておきます ここまでご丁寧に対応していただいたのは初めてです 本当にありがとうございました!
marasonPD

2021/03/19 16:08

なるほどです。fetchロジックが無い所に囚われてそちらに目を向けていませんでした。 何はともあれ良かったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問