Search code examples
javascriptiife

IIFE function not working after i export it


I need some help with a little issue that I am having? I have this IIFE in a module, I export the function and import it in the main app.js. As the function is a IIFE I expected that it calls itself but it does not seem to be the case. module content:

const playerModal = (function () {

    let modal = document.querySelector('.modal');
    let startBtn = document.querySelector('#startBtn');

    window.onload = function () {
        modal.style.display = 'block';
    };

    startBtn.onclick = function () {
        modal.style.display = 'none';
    };

    window.onclick = function (e) {
        if (e.target == modal) {
            modal.style.display = 'none';
        }
    };
})()

export {playerModal}

app.js content:

import { playerModal } from "./DOM/layout/playerInput";

it says: playerModal is declared but it's value is never read


Solution

  • There are two separate problems:

    1. Apparently, after the import, you never use playerModal.
    2. There's no point to exporting the result of calling the IIFE, as it doesn't return anything; your const playerModal will be undefined.

    I suspect what you're trying to do is import a module just for its side-effects. If so, you'd do it like this:

    The module:

    // No need for a function wrapper, modules run in their own scope
    let modal = document.querySelector('.modal');
    let startBtn = document.querySelector('#startBtn');
    
    window.onload = function () {
        modal.style.display = 'block';
    };
    
    startBtn.onclick = function () {
        modal.style.display = 'none';
    };
    
    window.onclick = function (e) {
        if (e.target == modal) {
            modal.style.display = 'none';
        }
    };
    
    export {}; // You may or may not need this empty export, depending on your environment
    

    app.js:

    import "./DOM/layout/playerInput";
    

    That just says "Import the module," without importing anything from it, which is how you load a module purely for side-effects.

    That said, often having a module that you load purely for side-effects isn't best practice. You might instead have it export a function that you can call with the selector strings for the modal and startBtn that sets up the handlers (and returns a function to remove them).

    The module:

    export function setupPlayerModal(modalSelector, buttonSelector) {
        let modal = document.querySelector(modalSelector);
        let startBtn = document.querySelector(buttonSelector);
    
        const windowLoad = () => {
            modal.style.display = 'block';
        };
        const buttonClick = () => {
            modal.style.display = 'none';
        };
        const windowClick = (e) => {
            if (e.target == modal) {
                modal.style.display = 'none';
            }
        };
    
        window.addEventListener("load", windowLoad);
        startBtn.addEventListener("click", buttonClick);
        window.addEventListener("click", windowClick);
    
        return () => {
            window.removeEventListener("load", windowLoad);
            startBtn.removeEventListener("click", buttonClick);
            window.removeEventListener("click", windowClick);
        };
    }
    

    app.js:

    import { setupPlayerModal } from "./DOM/layout/playerInput";
    
    const cleanupPlayerModal = setupPlayerModal('.modal', '#startBtn');
    // ...and then call `cleanupPlayerModal` if/when appropriate...
    

    Or if there's really no need to remove those handlers:

    import { setupPlayerModal } from "./DOM/layout/playerInput";
    
    setupPlayerModal('.modal', '#startBtn');