Ask A Question

Notifications

You’re not receiving notifications from this thread.

Adding Javascript to Rails 6

Tom Dringer asked in Javascript

Hi. I am fairly new to Rails and so far I have been unsucessful at adding any JS to my Rails 6 project. I have seen many videos and tutorials but i seem to run in to the same issue. Basically I get "xxx is undefined" for every script. I'm thinking my scripts are called at the wrong time or in the wrong order. I'm using Webpacker for my JS. Thanks

Reply

Hey Tom,

You'll have to share what you've got so we can help. If you can push up a repo to github, that would be most helpful. Otherwise just post your steps to reproduce the issue and we'll get you sorted. 👍

Reply

Sure, so for example. I am trying to add Toastr. I have installed via Yarn.

In my javascript/packs/application.js I have require("toastr")

I also have an application_helper.rb which i saw from a tutorial about adding Toastr so i have:

def toastr_flash
    flash.each_with_object([]) do |(type, message), flash_messages|
      type = 'success' if type == 'notice'
      type = 'error' if type == 'alert'
      text = "<script>toastr.#{type}('#{message}', '', { closeButton: true, progressBar: true })</script>"
      flash_messages << text.html_safe if message
    end.join("\n").html_safe
  end

Then I call toastr_flash in my views/layouts/application.html.rb.

The error i get is Uncaught ReferenceError: toastr is not defined

Any direction is appreciated.

Reply

Hey Tom,

That would be giving you the error because Javascript with inline script tags (that your helper is generating) are executed immediately. It does not wait for your webpacker Javascript to finish loading toastr before it runs. Hence the error.

You will want to wrap your code in a turbolinks:load event so that it waits until Turbolinks is ready and all your JS is loaded before it executes.

Reply

Example code I forgot to paste:

def toastr_flash
  flash.each_with_object([]) do |(type, message), flash_messages|
    type = 'success' if type == 'notice'
    type = 'error' if type == 'alert'

    text = <<~EOF
      <script>
        document.addEventListener("turbolinks:load", function() {
          toastr.#{type}('#{message}', '', { closeButton: true, progressBar: true })
        });
      </script>
    EOF
    flash_messages << text.html_safe if message
  end.join("\n").html_safe
end
Reply

Thanks for the feedback. I get the same error still, but this time much more detailed.


Uncaught ReferenceError: toastr is not defined
<anonymous> (index):38
dispatch turbolinks.js:75
notifyApplicationAfterPageLoad turbolinks.js:994
pageLoaded turbolinks.js:948
e turbolinks.js:872
start turbolinks.js:882
start turbolinks.js:1040
<anonymous> application.js:24
<anonymous> application-51d3c38d384dcac9fb08.js:2
Webpack 3
localhost:3000:38:5
<anonymous> (index):38
dispatch turbolinks.js:75
notifyApplicationAfterPageLoad turbolinks.js:994
pageLoaded turbolinks.js:948
e turbolinks.js:872
(Async: EventListener.handleEvent)
start turbolinks.js:882
start turbolinks.js:1040
<anonymous> application.js:24
<anonymous> application-51d3c38d384dcac9fb08.js:2

I have cleared my cache and all the usual things. Is there anything i should be looking out for in those errors?

I load my js in the head tag on my application layout file<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

Thanks

Reply

Webpacker doesn't make require available in the browser window, so you have to set that explicitly.

window.toastr = require('toastr')

Working example here for you: https://github.com/excid3/rails_toastr_example

Reply

Wow that really is above and beyond! Thank you so much!

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,464+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.