Reputation: 518
I did just a upgrade from RAILS 5 to RAILS 6 and I see that all rails views are not able to call a javascript function as before in RAILS 5.
I have an external javascript file located under
app/javascript/packs/station.js
This is is embeded in in app/views/layouts/application.html.erb as
<%= javascript_pack_tag 'station' %>
This is the code how I call the javascrpt function from html.erb file :
<%= text_field_tag(:station_text_field, ... ,
onkeyup: "javascript: request_stations(); ") %>
When I try to call a function thats is part of the station.js then I get an error in the browser developmer view: ReferenceError: request_stations is not defined
But I can also see in the brwoser view, under Debugger :
Webpack / app/javascript / packs / station.js
and the javascript function I want to call.
So it seems that this script was loaded by the browser.
In contrast, when I just copy and paste these few lines that represent this javascript function direct into the template view file (...html.erb), something like :
<script>
function request_stations ()
{
alert("calling request_stations");
};
</script>
then - it works as expected !
Upvotes: 1
Views: 3853
Reputation: 111
Agree with mhunter's answer. This post helped me get a grounding on this difference in Rails 6: https://blog.capsens.eu/how-to-write-javascript-in-rails-6-webpacker-yarn-and-sprockets-cdf990387463
What I don't see in your question is whether or not you did this in app/javascript/packs/application.js:
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require("station")
The big difference in Rails 6 is that you have to deliberately:
So if there is a function in station.js
that you want to use, connect the steps above. Start with a simple function in station.js
that fires upon DOMContentLoaded, and add a console.log("hey, station.js is alive and well"). If you don't see it, then something in those 3 steps is not right.
In pre-Rails6, you had a "garden" of JavaScript, just by virtue of being in the asset pipeline. In Rails 6, you have to be more deliberate.
Upvotes: 0
Reputation: 581
By default, variables/functions defined inside JavaScript files that are packed by Webpacker will not be available globally.
This is a good thing, because it prevents global naming conflicts. Generally speaking, you don't want to reference javascript functions/variables from your view. You instead want to write JavaScript in a way that attaches functionality to DOM nodes using their id
or other attributes.
Here is a basic example based on the code you provided:
# in your rails view
<%= text_field_tag(:station_text_field, ..., id: 'station-text-field') %>
// in your javascript
function request_stations() {
alert("calling request_stations");
};
const stationTextField = document.querySelector("#station-text-field");
stationTextField.addEventListener('keyup', (event) => {
request_stations();
});
Upvotes: 1