All threads / JavaScript functions disappear when using Rails 7
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

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

Want to stay up-to-date with Ruby on Rails?

Join 64,614+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2022 GoRails, LLC. All rights reserved.