2

I want to call a NodeJS class using only a Class name and a method name. How do I do this if I only have the string value of the class and method? Assuming I have this controller

export default class PageController extends BaseController {
    async mainMethod(request, response) {
        const mapClass = {
            class: "MyClass",
           method: "testMethod",
        };

        global.${mapClass.class}.${mapClass.method}(); <-- How do I call the class MyClass.testMethod();
   }
}

Now in my MyClass.js I have this function

// Inside MyClass.js
export default class MyClass {
    testMethod(params) {
       return "My response here";
    }
}

UPDATE:

import resolver from '../services/Resolver';

export default class PageController extends BaseController {
    async mainMethod(request, response) {
        const mapClass = {
            class: "MyClass",
           method: "testMethod",
        };

       let classInstance = new resolver[mapClass.class];
       classInstance[mapClass.method]();
   }
}

// Inside ../services/Resolver.js

import MyClass from './MyClass';

export {
    MyClass,
}

// Content of MyClass.js
// Inside MyClass.js
export default class MyClass {
    testMethod(params) {
       return "My response here";
    }
}

Call just hangs when i reached the let classInstance = new resolver[mapClass.class]; and just gives me a request timeout

MadzQuestioning
  • 3,341
  • 8
  • 45
  • 76
  • 1
    @Snow you are right, this is not valid JS. – Seblor May 09 '19 at 07:13
  • @Snow I'm just defining an object that contains the string value of the class and its method. And using that value I'm retrieving the class based from the string – MadzQuestioning May 09 '19 at 07:13
  • @Seblor updated my question. I missed out the controller name – MadzQuestioning May 09 '19 at 07:15
  • In your example MyClass is not a global. And it shouldn't be a global in modular envirionment. – Estus Flask May 09 '19 at 07:17
  • Possible duplicate of [How do I make JavaScript Object using a variable String to define the class name?](https://stackoverflow.com/questions/1366127/how-do-i-make-javascript-object-using-a-variable-string-to-define-the-class-name) – robe007 May 10 '19 at 19:40

2 Answers2

2

One way to do this is to create a lookup object so you can control what strings point to what classes rather than looking up things in some global space. Then you can grab the class object with a string key:

class MyClass {
    testMethod() {
       console.log("My response here");
    }
}

// create dispatch object mapping strings to classes
const classes = {MyClass}

class PageController  {
    mainMethod() {
        const mapClass = {
            class: "MyClass",
            method: "testMethod",
        };

        let instance = new classes[mapClass.class] // lookup class with string key
        instance[mapClass.method]()                // you can then lookup the method directly on the intance
   }
}

let p = new PageController()
p.mainMethod()
Mark
  • 90,562
  • 7
  • 108
  • 148
  • Hi @Mark Meyer I like your approach. But just a question what is const classes = {MyClass} do? I mean if I have 3 class should I write it something like this? const classes = {MyClass, MyClass2, MyClass3} – MadzQuestioning May 09 '19 at 07:26
  • 1
    Yes, exactly. It will create an object with keys the same as the class names. It's also safer if the strings are coming from untrusted sources. – Mark May 09 '19 at 07:27
  • 1
    Ok will try this and will accept your answer if this solves it – MadzQuestioning May 09 '19 at 07:31
  • Tried it and it didn't work. Not sure why but will update with what I have done – MadzQuestioning May 09 '19 at 11:10
  • 1
    Ok I tried it again and it worked but need to modify the let instance = new classes[mapClass.class] and added () to the end of let instance = new classes[mapClass.class] – MadzQuestioning May 10 '19 at 22:42
1

You should use brackets. Just like how you access an item in an array

global[mapClass.class][mapClass.method]()