Dynamically instantiate Script Include

Erik Gunther2
Kilo Guru

I'm trying to dynamically instantiate a Script Include. Based on some other forum responses here is what I've done in the Scripts-Background interface:

Script Include:

find_real_file.png

Scripts:
//Traditional approach: WORKS!
var obj = new global.TestAPI();
var result = obj.test();
gs.print(result);

//Dynamically calling method: WORKS!
var result2 = obj['test']();
gs.print(result2);

//Dynamically instantiating script include. FAILS!!!
var obj2 = this['TestAPI'](); //Fails
//var obj2 = this['global.TestAPI'](); //Fails
var result3 = obj2['test']();
gs.print(result3);

Note, I've tried some other things like

var obj2 = this['TestAPI()']; but this fails too.

 

 

1 ACCEPTED SOLUTION

Michael Jones -
Giga Sage

Well, this seemed to work for me, in a background script: 

var str = 'TestAPI'
var tm = new global[str]()
tm.test()

my .test() function was just gs.info('test called') and it showed up when I ran the code above. 

I hope this helps!

If this was helpful, or correct, please be kind and mark the answer appropriately.

Michael Jones - Proud member of the GlideFast Consulting Team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

View solution in original post

7 REPLIES 7

Michael Jones -
Giga Sage

Well, this seemed to work for me, in a background script: 

var str = 'TestAPI'
var tm = new global[str]()
tm.test()

my .test() function was just gs.info('test called') and it showed up when I ran the code above. 

I hope this helps!

If this was helpful, or correct, please be kind and mark the answer appropriately.

Michael Jones - Proud member of the GlideFast Consulting Team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

What if the script include was in a scoped application? Is there a way to make the use of "global" be a parameter? 

I was not able to find a way to fully pass in the scope + script include name as a string (or any other variable type). global[str] worked, but ["global"][str], not so much. Bracket notation only seems to work in place of a "." but can't be used as the first dynamically passed reference. 

So, making this fully, 100% dynamic does not appear to be possible, based on what I've tried. 

At least...not without using a method that I would strongly recommend against using, due to the potential risks. 

You could - with extreme caution - use eval() - the most dreaded, feared and hated of all JavaScript methods. 

You would need to create a global function that you can call in a scoped app (because eval() is not allowed in a scoped app) - basically a script include in the global scope that is named the same as the function you create, and contains only one function (remove the class) so, something like this: 

Name: dynamicNew

Script: 

function dynamicNew(str) {
        //notice we hard-code the "new" and "()" in the string, this at least gives you a
        //small measure of security as any other arbitrary code should throw an error.
        //for str pass in your scope + script include name

	var result =  eval('new ' + str + '()');
	return result;
}

 

Then, you could call it like this: 

var tm = global.dynamicNew('global.TestAPI');
tm.test()

Output: 
*** Script: test called

Again, any time you resort to eval, you open yourself to the potential that arbitrary (and malicious) code could be executed, so you will need to heavily weigh the risk vs. reward before implementing something like this. Not to be used lightly. 

I hope this helps!

If this was helpful, or correct, please be kind and mark the answer appropriately.

Michael Jones - Proud member of the GlideFast Consulting Team!

I hope this helps!
Michael D. Jones
Proud member of the GlideFast Consulting Team!

ChrisBurks
Mega Sage

This worked for me:

var theTest = new this['TestAPI']();