JavaScript functions disappear when using Rails 7
Hi,
I'm using Jumpstart Pro with Rails 7 and feel very confused as to what's happening with my JavaScript functions.
I have a Lessons view in which various buttons are used to play audio, switch to a different audio file etc. For example:
<button id="slow-audio-button" data-mp3="<%= @slow_audio %>" data-webm="<%= @slow_audio_webm %>@"
data-waveform="<%= @slow_waveform %>"
class="w-1/3 btn-small ml-2 bg-green-500 hover:bg-green-700 text-white font-bold rounded"
onclick="loadSlow()">Slow
</button>
To do this, I have a "peaks-setup.js" file with all the functions that's in app/javascript. Then in application.js, I have import "./peaks-setup".
This is the JS file:
document.addEventListener("turbo:load", () => {
(function (Peaks) {
const options = {
overview: {
container: document.getElementById('overview-container'),
waveformColor: 'blue',
},
mediaElement: document.querySelector('audio'),
dataUri: {
arraybuffer: document.getElementById('normal-audio-button').dataset.waveform
},
};
Peaks.init(options, function (err, peaks) {
window.instance = peaks;
});
})(Peaks);
});
function getAudioSource(audioSources, audioElement) {
const canPlayMessages = ['probably', 'maybe'];
for (const message of canPlayMessages) {
for (const source of audioSources) {
if (audioElement.canPlayType(source.type) === message) {
return source.src;
}
}
}
return null; // No playable audio URL
}
function loadNormal() {
const normalAudio = document.getElementById('normal-audio-button').dataset.mp3;
const normalAudioWebm = document.getElementById('normal-audio-button').dataset.webm;
const normalWaveform = document.getElementById('normal-audio-button').dataset.waveform;
const explanation = document.getElementById('explanation');
const audioElement = document.getElementById('audio');
const audioSources = [
{src: normalAudioWebm, type: 'audio/webm; codecs="opus"'},
{src: normalAudio, type: 'audio/mpeg'}
];
const normalAudioSource = getAudioSource(audioSources, audioElement)
const options = {
mediaUrl: normalAudioSource,
dataUri: {
arraybuffer: normalWaveform
}
};
instance.setSource(options, function () {
const view = instance.views.getView('overview');
view.setWaveformColor('blue');
});
instance.player.play();
explanation.textContent = "Click on the play button to listen to the conversation spoken at normal speed."
};
function loadSlow() {
const slowAudio = document.getElementById('slow-audio-button').dataset.mp3;
const slowAudioWebm = document.getElementById('slow-audio-button').dataset.webm;
const slowWaveform = document.getElementById('slow-audio-button').dataset.waveform;
const explanation = document.getElementById('explanation');
const audioElement = document.getElementById('audio');
const audioSources = [
{src: slowAudioWebm, type: 'audio/webm; codecs="opus"'},
{src: slowAudio, type: 'audio/mpeg'}
];
const slowAudioSource = getAudioSource(audioSources, audioElement)
const options = {
mediaUrl: slowAudioSource,
dataUri: {
arraybuffer: slowWaveform
},
waveformColor: 'green'
};
instance.setSource(options, function () {
const view = instance.views.getView('overview');
view.setWaveformColor('green');
});
instance.player.play();
explanation.textContent = "Click on the play button listen to the conversation spoken at slow speed."
};
function loadPractice() {
const practiceAudio = document.getElementById('practice-audio-button').dataset.mp3;
const practiceAudioWebm = document.getElementById('practice-audio-button').dataset.webm;
const practiceWaveform = document.getElementById('practice-audio-button').dataset.waveform;
const explanation = document.getElementById('explanation');
const audioElement = document.getElementById('audio');
const audioSources = [
{src: practiceAudioWebm, type: 'audio/webm; codecs="opus"'},
{src: practiceAudio, type: 'audio/mpeg'}
];
const practiceAudioSource = getAudioSource(audioSources, audioElement)
const options = {
mediaUrl: practiceAudioSource,
dataUri: {
arraybuffer: practiceWaveform
}
};
instance.setSource(options, function () {
const view = instance.views.getView('overview');
view.setWaveformColor('red');
});
instance.player.play();
explanation.textContent = "Guess the French translation of the phrase you hear. Then try to imitate what you hear."
};
function togglePlay() {
instance.player.isPlaying() ? instance.player.pause() : instance.player.play();
}
function rewind() {
let currentTime = instance.player.getCurrentTime();
instance.player.seek(currentTime - 1);
}
The part inside the event listener gets executed as expected but there is no sign of the functions afterwards when I run rails server.
Any idea what's going on? I'm probably missing something obvious but can't figure out what. Maybe I need to export the functions or something like that? Maybe I'm not importing the file the right way.
I would really appreciate some guidance.
Thanks
I didn't figure out why exactly my setup wasn't working so I tried another approach. I put my JS file in a Stimulus controller and then loaded that and it's working great.