Save JavaScript script text string as function variable to call it - javascript

I am fetching a JS script from a server, and getting the following string back:
(function(e){function t(t){for(var r,a,o=t[0],c=t[1] .....
I want to save it as a function variable so I can call it (and pass an argument).
I tried wrapping the string with a return (as suggested here) and then use Function() constructor to call it in order get the original function, but it returns undefined.
How can I do this?

Did you try eval https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
eval is a function that evaluates even if it is a function in string
something like this
const yourVariable = eval("function fromServerResponse(){console.log('executed');}")

Related

Can't use String.prototype.match as function for Array.some?

This doesn't work:
var s = '^foo';
console.log(['boot', 'foot'].some(s.match));
Uncaught TypeError: String.prototype.match called on null or undefined
But this does:
var s = '^foo';
console.log(['boot', 'foot'].some(function(i) { return i.match(s) }));
Why is this? I imagine somehow the String.prototype.match function is too "primitive" or something, but why exactly? Since I'm not using ES2015, the second version seems quite verbose. Is there an alternative?
EDIT
When I wrote the above, I actually got it backwards compared to my actual need, which was matching one string against a number of regexes. But thanks to the great answers and comments below, I get it: [/^foo/, /^boo/].some(''.match, 'boot').
Note: The value of this is determined by how the function is called! (exception: bound and arrow functions)
If you pass s.match to .some, then the function will be called with this set to the global object (e.g. window) not the string it "belongs" to.
I.e. it would be equivalent to this:
String.prototype.match.call(window, 'foo')
This cannot work because this has to refer to a string object.
You could solve this by binding the function to a specific this value:
['boot', 'foot'].some(s.match.bind(s));
Learn more about this:
MDN - this
You Don't Know JS: this or That?
How to access the correct `this` context inside a callback?
A function value in Javascript does not bring its object along with it. The value of s.match is a plain function value, with no knowledge that you happened to find it attached to s. In fact, no matter what String you access it through, it's always the same function value:
"foo".match === "bar".match
//= true
When you call a function through an object, Javascript sets this to that object for the duration of the function call. But as soon as anything comes between retrieving the function value and calling it, any object association is lost.
You can create a function that does remember a specific this value using bind, as in #Felix King's answer. someFunction.bind(someObject) has approximately the same meaning as function(arg1, arg2,...) { return someObject.someFunction(arg1, arg2,...); }, but it automatically handles the number of parameters properly.

My javascript constructor function method returns the entire method as text, instead of the expected return value

I am new to constructor functions, and I have the following in a .js file I include:
// should just get the number of customers out of the passed-in object
function myCustomers(customerObj) {
this.customerCount = function(customerObj) {
return customerObj.length;
};
}
On the .htm page which includes the .js file, I have the following:
var tmpObj = new myCustomers(custObj);
alert(tmpObj.customerCount);
What I expected was the alert to give me the number of customers, such as "1", etc. Instead, the alert contains the entire text of my function as though it were a string, like this:
function(customerObj) {
return customerObj.length;
}
I'm sure this is simple, but I have had a tough time googling for an answer, since my search contains very generic words like function, text/string, method, etc. FYI, this example has been pared down from a more complicated function, to hopefully make it easier to understand the question. I have tested this simpler function with the same result.
Thanks in advance!
It looks like in your alert, you are not actually calling the function, but instead passing the function itself to alert(). Try this:
alert(tmpObj.customerCount(custObj));
You might also want to change your myCustomers object to hang on to the object that is passed into the constructor, so you don't have to pass it in again when you call the function.
You should call the method like this:
var tmpObj = new myCustomers(custObj);
alert(tmpObj.customerCount(custObj));
Note the method parenthesis ;)

javascript function not getting called

In a Django template, I have a function
function show_graph(i){
$("#"+i+"seegraph").click(function(){
$("#"+i+"graph").show();
var qaa = {{ question_ids }};
var qid = qaa[i-1];
jQuery.ajax({
url: "/canvas/recreatechart/",
type: "get",
data: {qid: qid },
success: function(response){
var resp = jQuery.parseJSON(response);
alert("chart1"+i);
show_graph("chart1"+i, resp['chart_type'], resp['series_names'], JSON.stringify(resp['data1']), resp['answer'], resp['stories1'], resp['colors'], resp['stacked'], resp['title1']);
show_graph(resp['second_graph']+i,resp['chart_type'], resp['series_names'], resp['data2'], resp['answer'], resp['stories2'], resp['colors'], resp['stacked'], resp['title2']);
}
});
});
}
and an alert immediately inside show_graph, from which I've deduced that show_graph just isn't getting called, but I don't know why.
I don't have any errors in my console, when I tried alerting each argument in the first call one by one, they all showed up as expected, although "data1" showed up as "object Object" with a type of "object" (When I stringified data1, it came out as expected, although I don't know if that means anything).
Note that data1 is an array of dictionaries, the values of which are arrays of arrays. So, slightly complicated, and I'm not sure if js can parse the structure.
Is that why my function is not getting called? If not, what is it? If so, how do I fix it (given that this is the format I have to pass my data in). How can I find the problem?
EDIT: I would also like to note that I just tested something simple like [5] in place of data1, as that's what I was afraid was messing up the function call, but I'm still not getting the alert from show_graph, so I think that's not it after all.
You're already inside of a function called show_graph. Instead of calling the function you want, it's calling itself, and adding another click action to...a jquery selector that doesn't match anything. So rename your inner function and everything should work.
Do you have more than one function called show_graph()? Is the intention for the function to call itself from within the ajax success callback?
The function you posted has one parameter, i:
function show_graph(i){ ... }
Within the function you seem to be treating i as a number, e.g., at the point where you say qaa[i-1]. But then within your ajax call your success callback calls show_graph like this:
show_graph("chart1"+i, resp['chart_type'], resp['series_names'], JSON.stringify(resp['data1']), resp['answer'], resp['stories1'], resp['colors'], resp['stacked'], resp['title1']);
I don't know if you intended for it to call itself, but you're not passing in a single numeric parameter, you're passing in lots of parameters. (Of course JavaScript lets you do that if you use the arguments object, but in your case you're passing a string as the first argument but as I said above the function treats it as a number.)
A few thoughts...
Your function show_graph(i) is expecting a single argument. In the way you're using it in your selectors (like $("#"+i+"seegraph")), we can assume that the i refers to a string or a number. Later, you're sending show_graph a list to use in place of i, by calling:
show_graph("chart1"+i, resp['chart_type'], resp['series_names'], JSON.stringify(resp['data1']), resp['answer'], resp['stories1'], resp['colors'], resp['stacked'], resp['title1']);
It sounds like you might have another function somewhere that needs to show a graph (perhaps a 2nd show_graph, while this function creates the graph?
Perhaps your Ajax is failing (for one of many possible reasons) and so it isn't calling the success callback? Try adding an error: callback to see if it is called.
As for the [object Object] bit, that is a side effect of alert-ing objects. alert() converts its arguments to strings and the default Object toString method returns that "[object Object]". Use console.log (or directly inspect values in the debugger) to avoid this problem.
I think the problems is, show_graph attaches a click event to an element
When the click event happens, the callback for click is called, which performs an ajax call.
In successful ajax call, you call show_graph again, expecting it to fully execute, but doesn't. It just attaches another click event listener (considering an element is found)
So, your show_graph shouldn't bind the click event.

need to understand eval in the code for ajax response

The following code already exists in one of the javascript files i am working , may i know what does the following do
Its jquery ajax , i saw the response result and its a json string which is manually created by the backend.
I want to know what is eval doing here
success: function (response) {
var response= response.replace(/\\/g, "%5C");
eval(response);
},
eval executes the passed in string as if it were javascript code.
What exactly happens depends entirely on the contents of response.
That is, the value of the response variable that is passed to the eval function gets evaluated as normal javascript.
If response was "alert('Hello from evel!');", you would see an alert box with the text "Hello from evel!".
eval() executes a string as JavaScript code in the context of its execution context. Generally, this means scoped to whatever function it is in.
It is often used to evaluate a JSON string. Note that if you are eval()ing a JSON string, you should wrap it in parenthesis (( & )). The parenthesis means it will always be evaluated as an expression, not a block.

Javascript passing function into parameter?

I use the JQuery dialog and from the PHP I can build some add-in to the button. To be able to add code from the server side I pass a method by parameter. The problem is that FireBug tell me that the method is not defined :
okHandler is the parameter of this method call to raise the dialog and it contain a simple alert message for the moment, later some Ajax calls. Any idea why it doesn't work?
It looks like okHandler is a string containing a function declaration, not an actual function? You have
okHandler = "function anonymous(){alert('This is a test');}";
instead of
okHandler = function(){alert('This is a test');};
As John Kugelman notes, okHandler appears to be a string. It would work better if it was a function... However, if a string it must be, then you'll need to pass it through eval() to actually execute it:
eval( "(" + okHandler + ")()" )
Is the okHandler() function loaded (as a valid JS object -- not a String) at the time you get that error?
I believe it's not alright to call something like "if (foo != null)" if foo hasn't already been declared as a variable somewhere. FireBug would complain: "okHandler is no defined."
Try something like this...
var myHandlers = {};
// Load okHandler as a member of myHandlers when applicable here...
$('#dialog'+idbox)...
"Oky": function() {
myHandlers.okHandler && myHandlers.okHandler();
...
}
}

Categories

Resources