前提・実現したいこと
Ruby on RailsでJavaScriptを非同期で実装し他ので特定のビューファイルで反映をさせたい。
現在は、ビューファイルを開いて1回目だと非同期通信が起こらない → ブラウザをリロードすると非同期通信が正常に働き、解決する。
発生している問題・エラーメッセージ
JavaScriptで非同期のコードを書いた後に、デベロッパーツールのConsoleで入力を確認。 すると、 Uncaught TypeError: Cannot read property 'addEventListener' of null at price (price.js:5) というエラーが発生。一度、ブラウザをリロードすると、エラーが消え、JavaScriptの非同期通信が利用できる。 しかし、毎回リロードしないと非同期通信が起きないのでこのエラーを解決したい。
該当のソースコード
JavaScript
1 2function price() { 3 const market_price = document.getElementById("item-price"); 4 const add_tax = document.getElementById("add-tax-price"); 5 const profit = document.getElementById("profit"); 6 market_price.addEventListener("keyup", () => { 7 const selling_price = market_price.value; 8 let fee = selling_price * 0.1 9 let gains = selling_price * 0.9 10 add_tax.textContent = fee; 11 profit.textContent = gains; 12 }); 13} 14window.addEventListener("load", price);
変更したJavaScriptのコード
JavaScript
1 2function price() { 3 const market_price = document.getElementById("item-price"); 4 const add_tax = document.getElementById("add-tax-price"); 5 const profit = document.getElementById("profit"); 6 const XHR = new XMLHttpRequest(); 7 XMLHttpRequest.open("POST", `/items/${current_user_id}`, true); 8 XHR.responseType = "json"; 9 market_price.addEventListener("keyup", () => { 10 const selling_price = market_price.value; 11 let fee = selling_price * 0.1 12 let gains = selling_price * 0.9 13 add_tax.textContent = fee; 14 profit.textContent = gains; 15 }); 16} 17window.addEventListener("load", price); 18 19 20```### 該当のソースコード 21 22```html.erb 23 24<div class="items-sell-contents"> 25 <header class="items-sell-header"> 26 <%= link_to image_tag('furima-logo-color.png' , size: '185x50'), "/" %> 27 28 </header> 29 <div class="items-sell-main"> 30 <h2 class="items-sell-title">商品の情報を入力</h2> 31 <%= form_with model: @items, local: true do |f| %> 32 33 <%= render 'shared/error_messages', model: f.object %> 34 35 <%# 出品画像 %> 36 <div class="img-upload"> 37 <div class="weight-bold-text"> 38 出品画像 39 <span class="indispensable">必須</span> 40 </div> 41 <div class="click-upload"> 42 <p> 43 クリックしてファイルをアップロード 44 </p> 45 <%= f.file_field :image, id:"item-image" %> 46 </div> 47 </div> 48 <%# /出品画像 %> 49 <%# 商品名と商品説明 %> 50 <div class="new-items"> 51 <div class="weight-bold-text"> 52 商品名 53 <span class="indispensable">必須</span> 54 </div> 55 <%= f.text_area :name, class:"items-text", id:"item-name", placeholder:"商品名(必須 40文字まで)", maxlength:"40" %> 56 <div class="items-explain"> 57 <div class="weight-bold-text"> 58 商品の説明 59 <span class="indispensable">必須</span> 60 </div> 61 <%= f.text_area :discription, class:"items-text", id:"item-info", placeholder:"商品の説明(必須 1,000文字まで)(色、素材、重さ、定価、注意点など)例)2010年頃に1万円で購入したジャケットです。ライトグレーで傷はありません。あわせやすいのでおすすめです。" ,rows:"7" ,maxlength:"1000" %> 62 </div> 63 </div> 64 <%# /商品名と商品説明 %> 65 66 <%# 商品の詳細 %> 67 <div class="items-detail"> 68 <div class="weight-bold-text">商品の詳細</div> 69 <div class="form"> 70 <div class="weight-bold-text"> 71 カテゴリー 72 <span class="indispensable">必須</span> 73 </div> 74 <%= f.collection_select(:category_id, Category.all, :id, :name, {}, {class:"select-box", id:"item-category"}) %> 75 <div class="weight-bold-text"> 76 商品の状態 77 <span class="indispensable">必須</span> 78 </div> 79 <%= f.collection_select(:condition_id, Condition.all, :id, :name, {}, {class:"select-box", id:"item-sales-status"}) %> 80 </div> 81 </div> 82 <%# /商品の詳細 %> 83 84 <%# 配送について %> 85 <div class="items-detail"> 86 <div class="weight-bold-text question-text"> 87 <span>配送について</span> 88 <a class="question" href="#">?</a> 89 </div> 90 <div class="form"> 91 <div class="weight-bold-text"> 92 配送料の負担 93 <span class="indispensable">必須</span> 94 </div> 95 <%= f.collection_select(:delivery_fee_id, DeliveryFee.all, :id, :name, {}, {class:"select-box", id:"item-shipping-fee-status"}) %> 96 <div class="weight-bold-text"> 97 発送元の地域 98 <span class="indispensable">必須</span> 99 </div> 100 <%= f.collection_select(:area_id, Area.all, :id, :name, {}, {class:"select-box", id:"item-prefecture"}) %> 101 <div class="weight-bold-text"> 102 発送までの日数 103 <span class="indispensable">必須</span> 104 </div> 105 <%= f.collection_select(:ship_days_id, ShipDay.all, :id, :name, {}, {class:"select-box", id:"item-scheduled-delivery"}) %> 106 </div> 107 </div> 108 <%# /配送について %> 109 110 <%# 販売価格 %> 111 <div class="sell-price"> 112 <div class="weight-bold-text question-text"> 113 <span>販売価格<br>(¥300〜9,999,999)</span> 114 <a class="question" href="#">?</a> 115 </div> 116 <div> 117 <div class="price-content"> 118 <div class="price-text"> 119 <span>価格</span> 120 <span class="indispensable">必須</span> 121 </div> 122 <span class="sell-yen">¥</span> 123 <%= f.text_field :price, class:"price-input", id:"item-price", placeholder:"例)300" %> 124 </div> 125 <div class="price-content"> 126 <span>販売手数料 (10%)</span> 127 <span> 128 <span id='add-tax-price'></span>円 129 </span> 130 </div> 131 <div class="price-content"> 132 <span>販売利益</span> 133 <span> 134 <span id='profit'></span>円 135 </div> 136 </span> 137 </div> 138 </div> 139 <%# /販売価格 %> 140 141 <%# 注意書き %> 142 <div class="caution"> 143 <p class="sentence"> 144 <a href="#">禁止されている出品、</a> 145 <a href="#">行為</a> 146 を必ずご確認ください。 147 </p> 148 <p class="sentence"> 149 またブランド品でシリアルナンバー等がある場合はご記載ください。 150 <a href="#">偽ブランドの販売</a> 151 は犯罪であり処罰される可能性があります。 152 </p> 153 <p class="sentence"> 154 また、出品をもちまして 155 <a href="#">加盟店規約</a> 156 に同意したことになります。 157 </p> 158 </div> 159 <%# /注意書き %> 160 <%# 下部ボタン %> 161 <div class="sell-btn-contents"> 162 <%= f.submit "出品する" ,class:"sell-btn" %> 163 <%=link_to 'もどる', root_path, class:"back-btn" %> 164 </div> 165 <%# /下部ボタン %> 166 </div> 167 <% end %> 168 169 <footer class="items-sell-footer"> 170 <ul class="menu"> 171 <li><a href="#">プライバシーポリシー</a></li> 172 <li><a href="#">フリマ利用規約</a></li> 173 <li><a href="#">特定商取引に関する表記</a></li> 174 </ul> 175 <%= link_to image_tag('furima-logo-color.png' , size: '185x50'), "/" %> 176 <p class="inc"> 177 ©︎Furima,Inc. 178 </p> 179 </footer> 180</div> 181 182 183 184 185
試したこと
JavaScriptのコードというより、読み込みがうまくいってないため、起こっているのでは?
ruby on railsでjsファイルを読み込めるように設定をしてくれているが、特定のページに設定が出来ていないために、前のブラウザの情報が残っていることによって1回で読み込めていないのでは?
ディレクトリを確認すると、app/javascript/packs/price.js(今回適用するファイル)となっていた。
表示させたいrubyのnew.html.erbに
<%= javascript_include_tag "price.js" %>を記述すると、
Sprockets::Rails::Helper::AssetNotFound in Items#new
The asset "price.js" is not present in the asset pipeline.
というエラーが表示された。
assetファイル内にJavaScriptが無いことによるエラーだと思うが、特定のファイルを読み込ませる方法はこの場合どうすれば良いのかが分からない。
パスを指定するも、同様のエラーが出現してしまった。
説明足らずな部分があるかと思いますが、どうぞご回答よろしくお願いいたします。
補足情報(FW/ツールのバージョンなど)
ruby on rails 6.0.0を使用中になります。
大変お手数おかけしますがご確認よろしくお願いいたします。