ume

rails6でjavascriptでhello worldとデベロッパーツールのコンソールに表示しようとしたらnullが返って来た話

対象者

  • これからjavascriptrailsで動かそうとしている人.

  • javascriptをrails6で動かそうとするとコンソールにnullが表示される人

目次

  • エラー内容と経緯

  • 解決策

エラー内容と経緯

エラー内容 ⇨デベロッパーツールにnullと表示される.

処理の流れとしては home.jsで記載していることをapplication.jsで読み込んでapplication.html.erbでapplication.jsの内容を読み込むことでhome.html.erbのファイル内のhello worldを取得しようとしました。

home.html.erb

 <h1 id="hello">Hello World</h1>

javascript/packs/application.js

// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery')
//= require popper
//= require bootstrap-sprockets 


import 'bootstrap'
import '../src/application.scss'
import "./home"


// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)

javascirpt/packs/home.js

console.log(document.getElementById('hello'));

application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <title>猫検索</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <meta name="description" content="あなたのお好みの猫が探せます">
    <%= stylesheet_link_tag 'application', media: 'all', data: { turbolinks: true } %>
    <%= javascript_pack_tag 'application', data: { turbolinks: true } %>

    
  </head>

  <body>
    <header>
      <%= render 'layouts/header'%> 
    </header>
  <div class="background">
    <%= yield %>
    <%= image_tag "background.jpg" %>
  </div>
 
  </body>
</html>

↑のコードの処理の流れのイラストは↓

経緯 cloud9で開発していたのですが無料期間が終わりそうなのでローカルで開発し始めました。 そこでjavascriptを使ってコンソールにhello worldと出力しようとしました。 しかしなぜか以下のようにするとnullが出力されます。

原因と解決策

原因.
htmlファイルが読み込まれる前にjavascriptファイルが読み込まれているのでconsole.log(document.getElementById('hello'));でhtml要素を取得しようとしても、まだhtml読み込まれていないのでnullが出力される。 ちなみにapplication.html.erbの <%= javascript_pack_tag 'application', data: { turbolinks: true } %>これでjavascriptを読み込んでいる。htmlファイルは上から順番に実行されているのでhead内に書いているとjavascriptが先に読み込まれる。

解決策. html.ファイル読み込んでからjavascriptファイルを読み込む

.addEventListener(処理)

このメソッドを使うことでhtml.ファイルを読み込んでからjavascriptの(処理)を行なってくださいというメソッド。 なので上のメソッドを使用すると無事コンソールにhello worldを取得できました。

document.addEventListener('DOMContentLoaded', () => {
  const helloText = document.getElementById('hello');
  console.log(helloText.textContent);
});