سؤال

So here is my situation...

I'm coding something that has several API calls ( I'm at 10 now, and still growing ), that each use a separate function.

The functions all look similar to:

var today = new Date();
specificArray.length = 0;
$.getJSON("https://api-location1", function (data) {
    $.each(data, function (key, value) {
        specificArray[value.ID] = new Instance(value.ID, value.Name, {etc...});
    });
});
localStorage.setItem('lsItem1', today.toString());
localStorage.removeItem('aTable');
localStorage.setObject('aTable', specificArray);

The only things that differ in the various functions are the specificArray being modified from the JSON call, the api-address of a given call, the localStorage key references, and the number of items being passed in to the given Instance (which I use here as a generic name - each function has a different "new Instance" call. ( such as new Employee, new Project, new Product, etc ).

Now, I've tested this by creating a single function that passes in an object that contains all these various items, and uses an eval in the specifiedArray call...

myValues.table = 'aTable'; 
myValues.item = 'lsItem1';
myValues.apicall = 'https://api-location1'
myValues.id = 'value.ID';
myValues.instance = 'new Instance(value.ID, value.Name, {etc...})';
myAPICall(specifiedArray, myValues);

function myAPICall(theArray, someValues) {
  var today = new Date();
  theArray.length = 0;
  $.getJSON(someValues.apicall, function (data) {
    $.each(data, function (key, value) {
      specificArray[eval(someValues.id)] = eval(someValues.instance);
    });
  });
  localStorage.setItem(someValues.item, today.toString());
  localStorage.removeItem(someValues.table);
  localStorage.setObject(someValues.table, theArray);
}

And this seems to work fine - but the concern I have is the eval - which from everything I've read is evil and shouldn't be used - but on the same token - I think this is a good use of it, as its only evaluating specific strings assigned in code in a different function...

Or is there some better way to do this that I'm working around?

Thanks in advance...

NEW EDIT: Here is a JSFiddle that I'm using as an example - http://jsfiddle.net/e876q/

PLEASE NOTE: if I don't use the eval then this doesn't bring up the correct response when clicking the button!

ADDITIONAL EDIT : Here is a LiveWeave that is the same example ( My office blocks JSFiddle from running but not LiveWeave... go figure) http://liveweave.com/wf1oAU

هل كانت مفيدة؟

المحلول 3

After researching and trying different things, this is what worked for me...

I changed myValues.instance from

myValues.instance = 'new Instance(value.ID, value.Name, {etc...})';

to

myValues.instance = function (v) { this.table[v.someID] = new Instance(v.someID, v.someData);
myValues.table = [];

and then in my json function, i did:

$.getJSON(someValues.apicall, function (data) {
  $.each(data, function (key, value) {
    someValues.instance(value);
  }
}

which worked perfectly.

Thanks to everyone who submitted answers. Special thanks to GRaAL who got me on the right track talking about functions.

DocKraz

نصائح أخرى

You don't need to use eval here. Just pass the objects you're working on directly — no need to be passing strings around.

Instead of eval you may use functions, like this way (I omit some details of your script):

myValues.id = function getId(value) { return value.ID;}
myValues.instance = function createInstance(value) { return new Instance(...)}
myAPICall(specifiedArray, myValues);

function myAPICall(theArray, someValues) {
  $.getJSON(someValues.apicall, function (data) {
    $.each(data, function (key, value) {
      specificArray[someValues.id()] = someValues.instance();
    });
  });
}

it will be more flexible I think. Also if you often use the myAPICall with different parameters that could be a good idea to have a functions factory, like this:

function myAPICallCreator(someValues) {
    return function(theArray) {
       //...
       $.getJSON(someValues.apicall, function (data) {
          $.each(data, function (key, value) {
             specificArray[someValues.id()] = someValues.instance();
          });
       });
       //...
    }
}

var callFunction1 = myAPICallCreator({id: ..., instance: ..., apicall: ...});
var callFunction2 = myAPICallCreator({...});

//...

callFunction1(array1);
callFunction2(array2);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top