0

I want to export the function manualStrobeTimeout with the values especified within the manualBPM_text.addEventListener("change")'s scope. Right now, the console logs the export as undefined, meaning that the value doesn't change from when the variable was declared. How would I export the function with the values declared within that scope? Keep in mind that I cannot declare the function's values outside of the event listener, as this would interfere with the set intervals.

Here's the relevant module's code:

import { strobeActive } from "./onBtn.js"; // variable to check if ON button is active/pressed

// manual bpm variables definition and event listener
var manualBPM = 0;
var manualBPM_interval = 0;

const body = document.querySelector("body");
var ranTimes = 0;

// strobe duration variable definition and event listener
var duration = 100;
const slider = document.getElementById("MM-duration-slider");
slider.addEventListener("input", function() {
    duration = slider.value;
}, false);

var manualBPM_text = document.getElementById("manual-value");
var manualStrobeTimeout;

if (strobeActive == true) {
    manualBPM_text.addEventListener("change", function() {
        clearInterval(manualStrobeTimeout); // so that old value doesn't interfere with new value

        manualBPM = manualBPM_text.value;
        manualBPM_interval = (60 / manualBPM) * 1000;

        manualStrobeTimeout = function() {
            // repeat once the interval expires
            setInterval(function() {
                // trigger strobe
                body.classList.remove("bg-black");
                body.classList.add("bg-white");

                // kill strobe once the strobe duration expires
                setTimeout(function() {
                    body.classList.remove("bg-white");
                    body.classList.add("bg-black");
                }, duration);
                
                ranTimes++;
                console.log("BPM: " + manualBPM + " (source: " + BPMvalueSource + ") | Strobe duration: " + duration + "ms | " + "Times ran: " + ranTimes);
            }, manualBPM_interval);
        }
    }, false);
}

export { manualBPM_text };
export { manualStrobeTimeout };

I want use the imported function in the following statement (on a seperate JS file):

if (BPMvalueSource == "manual") { 
            manualStrobeTimeout();
            console.log(manualStrobeTimeout()); // returns "undefined"
        } else if (BPMvalueSource == "tap") { 
            tapBPM_strobe();
        }

I have tried using window. to set the function as global, but to no avail. I have also made sure that I am importing and exporting correctly, and also tried using a dynamic import. This also did not work. Both JS files have the attribute type="module" especified.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
SubZone
  • 5
  • 2
  • I don't think there's an issue with your exports/imports, the function is called just fine (if it wasn't, you'd get an exception). It's just that `manualStrobeTimeout` does not `return` anything! – Bergi Feb 13 '23 at 15:07
  • @jabaa It definetly does help. As I am new to JavaScript, I was not aware of the asynchronicity and callback concepts. I'm still unsure on how I will implement a callback on my code but I will try to figure it out. Thank you for your help. – SubZone Feb 13 '23 at 15:07

2 Answers2

0
  1. The clearInterval was not clearing the interval.
  2. The interval would not even be able to run since the wrapping function was never called
  3. You cannot export non-constat values
let lastManualBPMValue;

if (strobeActive == true) {
    manualBPM_text.addEventListener("change", function() {
        lastManualBPMValue = manualBPM_text.value;
    }, false);
}

export { manualBPM_text };

let manualStrobeTimeout;
export function manualStrobe() {
    clearInterval(manualStrobeTimeout); // so that old value doesn't interfere with new value
    manualBPM_interval = (60 / lastManualBPMValue) * 1000;
    manualStrobeTimeout = setInterval(function() {
        ...
    }, manualBPM_interval);
}
Akxe
  • 9,694
  • 3
  • 36
  • 71
  • "*You cannot export non-constat values*" - sure you can. Because it's not values that are exported but variables. – Bergi Feb 13 '23 at 15:30
  • Thanks a lot for your answer, it worked! I only had to make some changes to trigger the function on the event listener itself, in order for the values to be constantly updated. Besides that, your logic is correct. If it wasn't for your answer I would have been stuck on this for days! Thank you so much kind stranger, you are doing god's work out here. – SubZone Feb 13 '23 at 16:35
0

The function that is assigned to the manualStrobeTimeout variable has no return statement in it, and as such will always return undefined when executed.

If you want to check that manualStrobeTimeout is assigned a value, you may want to do console.log(manualStrobeTimeout) instead, which will log the value assigned to the variable.

With console.log(manualStrobeTimeout()) you are executing the manualStrobeTimeout function, and its return value will be fed to console.log. The return value of a JavaScript function is undefined by default.

Keep in mind that manualStrobeTimeout will not be a function unless the "change" event listener has triggered.

You didn't directly ask about this, but you may also want to look at the documentation for clearInterval(). The code is attempting to call clearInterval on a function, not an interval ID.

martinstark
  • 187
  • 8