skip to Main Content

I want to call the instance methods whose name is passed with the func input element but my code fails because it can’t find the TestClass instance methods in the global window. How can I achieve this?

class TestClass {
  func = document.getElementById('func');

  result = document.getElementById('result');

  func1 = () => {
    this.result.innerHTML = 'func1 called';
  };

  func2() {
    this.result.innerHTML = 'func2 called';
  }

  funcListener = () => {
    window[this.func.value]();
  };

  constructor() {
    this.func.addEventListener('change', this.funcListener);
  }
}

new TestClass();
functest.html

<!doctype html>
<html lang="en-US">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <title>functest</title>
</head>

<body>
  <input id="func" placeholder="enter function to call: func1, func2" type="text" maxlength="200">
  <label id="result" for="func">result</label>
</body>

2

Answers


  1. window[this.func.value]() – your functions are wrapped inside class, not global, so use this[this.func.value]() instead.

    class TestClass {
      func = document.getElementById('func');
    
      result = document.getElementById('result');
    
      func1 = () => {
        this.result.innerHTML = 'func1 called';
      };
    
      func2() {
        this.result.innerHTML = 'func2 called';
      }
    
      funcListener = () => {
        this[this.func.value]();
      };
    
      constructor() {
        this.func.addEventListener('change', this.funcListener);
      }
    }
    
    new TestClass();
    functest.html
    
    <!doctype html>
    <html lang="en-US">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,initial-scale=1">
      <title>functest</title>
    </head>
    
    <body>
      <input id="func" placeholder="enter function to call: func1, func2" type="text" maxlength="200">
      <label id="result" for="func">result</label>
    </body>
    Login or Signup to reply.
  2. The problem arises from attempting to access DOM elements directly within the class definition. However, during instantiation, these elements may not be present in the DOM yet.

    You can move the assignment of func and result properties inside the constructor

    class TestClass {
      constructor() {
        this.func = document.getElementById('func');
        this.result = document.getElementById('result');
    
        this.funcListener = this.funcListener.bind(this);
    
        this.func.addEventListener('change', this.funcListener);
      }
    
      func1() {
        this.result.innerHTML = 'func1 called';
      }
    
      func2() {
        this.result.innerHTML = 'func2 called';
      }
    
      funcListener() {
        const funcName = this.func.value.trim();
        if (funcName === 'func1') {
          this.func1();
        } else if (funcName === 'func2') {
          this.func2();
        } else {
          this.result.innerHTML = 'Invalid function name';
        }
      }
    }
    
    new TestClass();
    <input
          id="func"
          placeholder="enter function to call: func1, func2"
          type="text"
          maxlength="200"
        >
        <label id="result" for="func">result</label>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search