TransWikia.com

How do I make a JavaScript function available globally in Rails 6 with Webpack?

Stack Overflow Asked by Hassam Saeed on January 7, 2021

As a beginner on Rails 6. Whenever, i click on the Roar Link then it gives me the following error. The following files are attached below. I just want to add custom file(demo.js) into my code so that i can test the behavior of JavaScript in my following code. Java Script behavior on Rails 5 is different from the Rails 6.

Kindly give me the better solution so that i can solve my problem. I tried all of answers on stack overflow.

Application.html.erb (views/layouts/application.html.erb)

<!DOCTYPE html>
<html>
  <head>
    <title>SimpleCms</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    
  </head>

  <body>
    <%= yield %>
  </body>
</html>

demo.js (app/javascript/packs/demo.js)

function jsRoar(name) {
    alert('I am ' + name + '. Hear me roar!');
  }

application.js (app/javascript/packs/application.js)

require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("packs/demo")

index.html.erb (views/demo/index.html.erb)

<h1>This is the index Page</h1>
<br/>
<%= link_to('All Subjects',subjects_path) %>

<%= link_to('Roar', '#', :onclick => "jsRoar('JavaScript'); return true;") %>

demo_controller.rb

class DemoController < ApplicationController
  
  layout 'application'
  
  def index
  render ('index')
  end

  def hello
  render ('hello')
  end

end

GEM File

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.2'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: 
https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

One Answer

You're thinking of the old way of doing it. I've explained it here:

https://stackoverflow.com/a/56549843/1238868

Here's a more modern way of doing what you're trying.

<%= link_to('Roar', '#', data: {roar: 'JavaScript'}) %>

In demo.js:

document.addEventListener("turbolinks:load", function() {
  document.querySelectorAll('[data-roar]').forEach(function(roaring_link) {
    roaring_link.addEventListener('click', function(event) {
      let name = roaring_link.dataset['roar']
       alert('I am ' + name + '. Hear me roar!');
       event.preventDefault();
       event.stopPropagation();
       return false;
    });
  });
});

Note that the code in demo.js is self-contained and simply looks at the document and attaches the desired functionality to the links. You specify what links those are by adding a data attribute with the data that you wish to pass to your javascript function.

This might seem complicated but after you get the hang of it you'll find your javascript is really clean and easy to maintain.

Correct answer by Michael Chaney on January 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP