skip to Main Content

I am trying to dynamically call a function based on its name stored in a string using bracket notation on the window object. I have also tried using eval() to no success.

The project has been bundled using webpack.

More specifically I am constructing the function name using the text content of three buttons and then I want to call the corresponding function.

The error I am receiving is Uncaught TypeError: window[element.textContent] is not a function at HTMLButtonElement.

I have also tried using eval() and new Function to no success.

Update: When I run this with a live-server in vscode the problem persist however if I take all the js modules and place them in one JS file linked to the index.html file and open the html locally it works as it should.

Please JS below

import populateAboutPage from "./aboutPage.js";
import populateMenuPage from "./menuPage.js";
import populateContactPage from "./contactPage.js";

const btns = document.querySelectorAll(".btn");

btns.forEach((element) => {
  element.addEventListener("click", () => {
    // Dynamically call the function based on button text content
    window[`populate${element.textContent}Page`]();
  });
});

HTML:

<nav class="nav-btns">
        <button class="btn">About</button>
        <button class="btn">Menu</button>
        <button class="btn">Contact</button>

      </nav>

webpack.config:

   

     const path = require("path");
        const HtmlWebpackPlugin = require("html-webpack- 
        plugin");
    
        module.exports = {
          mode: "development",
          entry: "./src/index.js",
          output: {
            filename: "[name].js",
            path: path.resolve(__dirname, "dist"),
            clean: true,
          },
          module: {
            rules: [
              {
                test: /.css$/,
                use: ["style-loader", "css-loader"],
              },
              {
                test: /.(png|svg|jpg|jpeg|gif)$/i,
                type: "asset/resource",
              },
              {
                test: /.(woff|woff2|eot|ttf|otf)$/i,
                type: "asset/resource",
              },
            ],
          },
          devtool: "inline-source-map",
          node: {
            global: true,
          },
          devServer: {
            static: "./dist",
          },
          plugins: [
            new HtmlWebpackPlugin({
              title: "Restaurant Page",
              template: "./src/index.html",
            }),
          ],
          optimization: {
            runtimeChunk: "single",
          },
        };

2

Answers


  1. Chosen as BEST ANSWER

    I think the issue has been with webpack config and although I have not found how to set these correctly I have found that by attaching the functions to the window object the script now runs. Don't think this is great practice but it has solved the issue. Solution mainly came from here

    Please see below:

    import populateAboutPage from "./aboutPage.js";
    import populateMenuPage from "./menuPage.js";
    import populateContactPage from "./contactPage.js";
    
    window.populateAboutPage = populateAboutPage; 
    window.populateMenuPage = populateMenuPage;
    window.populateContactPage = populateContactPage;
    
    const btns = document.querySelectorAll(".btn");
    
    btns.forEach((element) => {
      element.addEventListener("click", () => {
        // Dynamically call the function based on button text content
        window[`populate${element.textContent}Page`]();
      });
    });


  2. import populateAboutPage from "./aboutPage.js";
    import populateMenuPage from "./menuPage.js";
    import populateContactPage from "./contactPage.js";
    
    const functions = {
      populateAboutPage,
      populateMenuPage,
      populateContactPage
    }
    
    functions[`populate${element.textContent}Page`]()
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search