New Discussion

Notifications

You’re not receiving notifications from this thread.

JavaScript functions disappear when using Rails 7

2
Javascript

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

Did you ever get this figured out?

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.

Join the discussion
Create an account Log in

Learning Ruby on Rails? Join our newsletter.

We won't send you spam. Unsubscribe at any time.