views:

940

answers:

6

Hey right now I'm using jQuery and I have some global variables to hold a bit of preloaded ajax stuff (preloaded to make pages come up nice and fast):


$.get("content.py?pageName=viewer", function(data)
    {viewer = data;});
$.get("content.py?pageName=artists", function(data)
    {artists = data;});
$.get("content.py?pageName=instores", function(data)
    {instores = data;});
$.get("content.py?pageName=specs", function(data)
    {specs = data;});
$.get("content.py?pageName=about", function(data)
    {about = data;});

As you can see, we have a huge violation of the DRY principle, but... I don't really see a way to fix it... any ideas?

maybe an array?

+1  A: 

You can avoid eval using new Function:

var names = ['viewer', 'artists', 'instores', 'specs', 'about'];
for (var i = 0; i < names.length; i++)
   $.get("content.py?pageName=" + names[i], new Function('data', names[i] + ' = data;'));

It's not a lot better though tbh

Greg
A: 

You can call only one time that page, and returning a json object instead of text

{
viewer:'me',
artists:'you',
instores:'instores',
specs:'specs',
about:'about'
}

and eval that Since now you're calling N times your server, this slow down all, you should reconsider your logic!

PS. as I write i saw the RoBorg answer, you see, when using new Function you are using eval under the hood, so if you want to use it go for it (in some browser is faster too)

kentaromiura
+5  A: 

Using the jQuery each method to iterate through an array of page names and then setting a global (in window scope) variable:

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page,
            new Function("window[" + page + "] = arguments[0]"));
    }
);

Update: Actually, you don't even need the "new Function":

jQuery.each(
    ["viewer", "artists", "instores", "specs", "about"],
    function (page) {
        $.get("content.py?pageName=" + page, function () { window[page] = arguments[0]; });
    }
);
Ates Goral
Nice use of jQuery.each()!
Shog9
I like the jquery... but Shog's answer is the one that actually solved my problem :/ Thanks though :)
Jiaaro
+4  A: 

You don't need eval() or Function() for this. An array, as you suspected, will do the job nicely:

(function() // keep outer scope clean
{
   // pages to load. Each name is used both for the request and the name
   // of the property to store the result in (so keep them valid identifiers
   // unless you want to use window['my funky page'] to retrieve them)
   var pages = ['viewer', 'artists', 'instores', 'specs', 'about'];

   for (var i=0; i<pages.length; ++i)
   {
      // "this" refers to the outer scope; likely the window object. 
      // And will result in page contents being stored in global variables 
      // with the same names as the pages being loaded. We use the with({})
      // construct to create a local scope for each callback with the
      // appropriate context and page name.
      with ({context: this, pageName: pages[i]})
         $.get("content.py?pageName=" + pageName, function(data)
            {context[pageName] = data;});
   }

})(); // close scope, execute anonymous function

// at this point, viewer, artists, etc. are populated with page contents 
// (assuming all requests completed successfully)
Shog9
A: 

This doesn't use eval, though it's a little more wordy.

function get_content(name){
   $.get("content.py?pageName=" + name, function(data){ window[name] = data;});
}

var names = ['viewer', 'artists', 'instores', 'specs', 'about'];
for (var i = 0; i < names.length; i++)
    get_content(names[i]);

But one of the of answerers made a good point, you should probably try and combine all these requests into one otherwise your server will be hit 6 times for dynamic content on each request of the page.

Daniel Beardsley
A: 

Most of these proposed solutions avoid the use of eval. That practice is further reinforced in Doduglas Crockford's " Code Conventions for the JavaScript Programming Language" which says in part

"eval is Evil

The eval function is the most misused feature of JavaScript. Avoid it.

eval has aliases. Do not use the Function constructor."

DOK