🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

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

Ruby

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

Ruby on Rails 6

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

Q&A

解決済

1回答

400閲覧

【Vue.js】ブラウザのConsoleに「undefind」と出てくる際の修正方法

katahik

総合スコア79

Vue.js

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

Ruby

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

Ruby on Rails 6

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

0グッド

0クリップ

投稿2021/01/07 21:24

標記の件について質問させていただきます。
RailsとVue.jsで自作アプリを開発しております。
イメージ説明

現状・実現したいこと

【現状】

イメージ説明

アプリは正しい挙動をしているのにも関わらず、現在、ブラウザのConsoleに上記のエラーがでております。

【実現したいこと】
このエラーを解消したい。

該当のソースコード

app/controllers/api/items_controller.rb

Ruby

1class Api::ItemsController < ApplicationController 2 require "date" 3 4 def index 5 @random_items = fetch_items 6 end 7 8 def update 9 @selected_id = params[:id] 10 # idを頼りに該当のitemを探す 11 @selected_item = Item.find(@selected_id) 12 # そのアイテムのpointsカラムに+1 13 @selected_item.points += 1 14 # 保存 15 @selected_item.save 16 17 @random_items = fetch_items 18 # JSON形式で出力する 19 render json: @random_items 20 end 21 22 private 23 # fetchとは呼び出すこと 24 # 今現在、開催中の大会から、2つのitemの呼び出す 25 def fetch_items 26 in_session_competition = 27 Competition.find_by(period_start: -Float::INFINITY..Date.today, period_end: Date.today..Float::INFINITY) 28 29 # 今日開催中の大会のitemsをRANDOMメソッドで並び替え、その中の2つを@random_itemsに入れて、テンプレートへ渡す 30 in_session_competition.items.order("RANDOM()").limit(2) 31 end 32end 33

app/views/home/index.html/erb

<h1 id="heading">Click either you "like".</h1> <div id="app"> <div id="pictures"> <div id="picture" v-for="item in items"> <!-- @click.preventとすることで画面遷移させない--> <!-- clickしたときは、updataItemが発火--> <a @click.prevent="updataItem(item.id)"> <!-- public/item_images の中に画像を格納しておく。--> <!-- DBには画像のデータの名前を入れておく--> <img :src="'/item_images/' + item.image" width="500px" height="500px"/> <div> {{item.name}} </div> </a> </div> </div> </div> <script> new Vue({ el: "#app", data() { return { // itemsは配列でくるから、配列を定義しておく items:['',''], } }, mounted() { this.setItems(); }, methods: { // setCompetitionsメソッドを定義 setItems: function () { // GETメソッドでapi/itemsとしたとき // ここには、json形式になった@random_itemsがある(index.json.jbuilderで定義した) axios.get('/api/items') // 成功したら、 .then(response => ( // Axiosで呼び出したAPIの情報をitemsに格納 this.items = response.data )) }, // itemをクリックしたとき、そのクリックしたほうのitemのidが渡って来る updataItem: function(item_id){ // PUTメソッドでapi/items/item_idとする axios.put('api/items/'+item_id) // 上が成功したら .then(response => ( // Axiosで呼び出したAPIの情報をitemsに格納 this.items = response.data )) } } }); </script>

app/views/api/items/index.json.jbuilder

json.array! @random_items, :id,:name, :image,:points,:competition_id

config/routes.rb

Rails.application.routes.draw do root 'home#index' resources :competitions,only:[:index,:show] namespace :api,format:'json' do resources :items,only:[:index,:update] end end

試したこと

  • ログの確認

log

Started GET "/item_images/undefined" for ::1 at 2021-01-08 05:51:00 +0900 ActionController::RoutingError (No route matches [GET] "/item_images/undefined"):

ログを確認したところ、やはりエラーがでてました。getリクエストで/items_images/undefindeがない。とのことで、undefinde(本来であれば、画像の名前が乗ってくる箇所)になっていることが原因だと思いました。

  • 怪しい箇所を削除

app/views/home/index.html.erb

<img :src="'/item_images/' + item.image" width="500px" height="500px"/>

上記の行を削除したところ、item_images/undefinedのエラーは消えました。
ということはこのitem.imageがundefindだからエラーが出るのかなと思います。

しかし、先述したとおり、正しい挙動しており、該当箇所にもデータが渡ってきております(画像が表示されているため)。

お忙しいところ、恐縮ですが、ご教示いただければ、幸いです。

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

  • ruby 2.7.0p0
  • Rails 6.1.0
  • sqlite

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

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

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

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

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

m.ts10806

2021/01/07 21:50 編集

HTMLコード上はどうなってるのでしょう。 デベロッパツールか「ソースを表示」で該当箇所を確認してみてください。
katahik

2021/01/07 22:17 編集

m.ts10806 様 以下、ソースです。 <div id="pictures"> <div id="picture" v-for="item in items"> <!-- @click.preventとすることで画面遷移させない--> <!-- clickしたときは、updataItemが発火--> <a @click.prevent="updataItem(item.id)"> <!-- public/item_images の中に画像を格納しておく。--> <!-- DBには画像のデータの名前を入れておく--> <img :src="'/item_images/' + item.image" width="500px" height="500px"/> <div> {{item.name}} </div> </a> </div> </div> このitem.imageがundefinedになっていることが,原因だとは思っています。 また、/api/items にアクセスすると [{"id":3,"name":"monster3","image":"monster3.jpeg","points":54,"competition_id":1},{"id":2,"name":"monster2","image":"monster2.jpeg","points":50,"competition_id":1}] ということで、画像名は取れていることが確認できます。
m.ts10806

2021/01/07 22:23

組んだコードではなくブラウザに表示されたHTMLを確認してください。
katahik

2021/01/07 22:29

「右クリック」→「ページのソースを表示」で表示されるコードは上で回答したコードになるんですが、その中の違うところを見るということでしょうか?すみません、、、
m.ts10806

2021/01/07 23:47

あれ。Vueってそのまま{{item.name}}とか出るんですね。失礼。
guest

回答1

0

ベストアンサー

setItems vue上のこの処理が呼ばれてから
実際にitemsにセットされるまでの間でも
vueに初期セットされている items が ['','']と
定義されているためv-forが回り item.image が呼ばれているせいかなと
自分の中で整理して予想いたしました。

こちらご確認をお願いします。

投稿2021/01/07 23:26

ransuS_T

総合スコア106

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

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

katahik

2021/01/08 03:30

ransuS_T 様 ご指摘いただいた内容を元に items:"",とすることで、エラー解消できました。(Console及びlogでエラーが出てこない) ありがとうございました。 ひとつ確認させてください。 items:['','']としていたときは、それにv-forが反応してしまい、空の配列にitem.imageとしたから、エラーが出てしまった。 今回、items:""として、何も定義しなかったからv-forも反応しなかったということでしょうか?
ransuS_T

2021/01/08 03:40

v-forの動きを考えてみましょう 要素があればまわす というようなことをしており 上記の items:"" であれば要素がないため v-forが回らないためv-for内にある要素も作られない というようなことになっていると思います。 一つご指摘させてもらうなら items:[] こう書くのがいいかなと思います。 以上が自分の考えになります。 参考になれば幸いです。
ransuS_T

2021/01/08 04:08 編集

また items:["",""] とどうしても書きたい場合には itemを読み込んでいる要素に対し 表示前に表示できるか判定してあげるという方法もあると思います。 例) <img v-if="item.image" :src="'/item_images/' + item.image" width="500px" height="500px"/> これをイメージ以外(item.name や id)でもちゃんと条件判定してあげれば エラーが表示されることはなくなるんじゃないかなと思います。
katahik

2021/01/08 08:44

items:[]でした場合も、items:["",""]でv-ifでした場合もどちらとも、正しい挙動を取れました。 本当に勉強になりました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問