Ask A Question

Notifications

You’re not receiving notifications from this thread.

JavaScript functions disappear when using Rails 7

benjaminhouy asked in 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

Reply

Did you ever get this figured out?

Reply

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.

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.