1

I was wondering how I can get a function from an AJAX request, like this:

Let's say I have a file called myfunction.js, that looks like this:

function(bar){
 alert(bar);
}

Can I retrieve it via Ajax as a function, like this?

var foo = $.ajax({url:'myfunction.js',async:false}).responseText;

And run it like this?

foo(bar);

The reason I ask is because I know responseText is a string,
so I'm not really sure if JavaScript will understand that it is a function.

Is there a way to convert a string into a function?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Doug
  • 859
  • 1
  • 9
  • 20
  • 2
    jQuery has a `getScript` method you can use to load external scripts and fire a callback function once available. – Phil Parsons Sep 12 '11 at 19:49

4 Answers4

3

In your JS file, give the function a name.

function foo(bar){
   alert(bar);
}

Then use $.getScript to load it.

$.getScript('myfunction.js', function(){
   foo('test');
});
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
1

Absolutely:

foo = eval('(' + foo + ')');

foo(bar);

You could use new Function but in my testing it doesn't work on some versions of IE.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Be careful! eval'ing a function doesn't work in some versions of IE. See http://stackoverflow.com/questions/4599857/is-eval-and-new-function-the-same-thing/4599932#4599932 A workaround at the time I answered that question was to use `eval('[function a(){return 5}][0] ')` – Ruan Mendes Sep 12 '11 at 19:56
1

I ended up using new Function instead of eval, eval executes the code as soon as it's parsed, which is not what I was after.

This is what I ended up doing, and it works very nicely in firefox, chrome, and IE 7+ (no errors at all)

function createMyFunction(code){return new Function('params',code)};

var thecode = $.ajax({
                  url:      'myCode.js',
                  async:     false,
                  dataType: 'html'

               }).responseText

myFunction = createMyFunction(thecode);

I know the createMyFunction is pretty lazy in terms of not being able to define different arguments, but using a single params map works for my templating scenario quite well.

Note the dataType:'html' in the ajax request, if you don't specify a plain text mime type, jQuery will actually recognize that you are getting JS code and try to parse it, which generally ends up throwing a parse error or sometimes "Uncaught TypeError: params is not defined".

With this, I am able to have template files that specify template-specific events, and keep them organized in the same way as the markup and css files for that template.

Thanks for the help everyone, the reason I chose the answer that I did is because the link at the end pointed me in the right direction.

Cheers, D

Doug
  • 859
  • 1
  • 9
  • 20
0

One thing to beware.

Chrome and IE don't allow you to eval an anonymous function directly (FF is fine). That is

// Throws Syntax Error in Chrome, Object expected in IE 8
var fun = eval('function(){return 5}'); fun(); 

A hackaround is to put it in an array, doesn't seem very reliable for the future:

var fun = eval('[function (){return 5}][0]'); fun();

The only safe way would be to make sure your functions are named, since the following works fine in all browsers:

eval('function a(){return 5}]'); a(0);

See Are eval() and new Function() the same thing? for further discussion

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217