Eval a string to a callable JS function - javascript

I need to eval a function kept as string and then use it in JS code, here's the scenario:
Step 1
<textarea id="function_text">function test(e){ alert(e.id); }</textarea>
Step 2
var thatFunction = eval($("#function_text").val()); // returns undefined
Step 3
thatFunction.call({id: 100});
Is there a way to do that?
P.S. I'm aware of all security considerations, I just need 100 to be alerted at step 3!

I'm going to give you a warning, don't do it, but here is how:
var thatFunction = Function('return ' + $("#function_text").val())();
thatFunction.call({id: 100});

The code in the string will be evaluated as function declaration and not produce a return value, and that's why eval returns undefined.
You could concatenate the function declaration with your variable assignment:
eval('var thatFunction = ' + $("#function_text").val());
or simply call the function by the name it has (it you know it):
test.call({id: 100});
You might not want to use the variable name in the string. That's not a problem, all you have to do is force eval to consider the function definition as function expression and have it return the function. For example, you can do this by using the grouping operator:
var thatFunction = eval('(' + $("#function_text").val() + ')');
A more obscure way would be the comma operator:
var thatFunction = eval('0,' + $("#function_text").val());

Related

LineBreak in console object

Line break in javascipt string console
console.log("Foo" + "\n" + "Bar");
Line break in javascript object console
console.log({ value : "Foo\nBar" });
Is it possible to add linebreaks in javascript objects.
The answer is no: when you print an object to the console log, strings will be written as javascript objects (similar but not identical to what you'd get if you explicitly converted them into JSON, like console.log(JSON.stringify(object))).
If you want for some reason to print your strings with line breaks, you'd have to implement the object-to-string conversion yourself; perhaps with something like this:
function customString(object) {
let string = '{\n';
Object.keys(object).forEach(key => {
string += ' "' + key + '": "' + object[key] + '"\n';
});
string += '}';
return string;
}
console.log(customString({ value: "Foo\nBar" }));
(It sounds like you have an idea in mind of exactly how you want this output to look, so adjust the function above until it works as expected.)
You can make JSON pretty with automatic line breaks using:
console.log(JSON.stringify({ test: { key: { inner: 'val' } }}, null , 2))
Where 2 is the number of spaces/indent for each level.
You can use ES6:
console.log(`hello
world`)
will produce:
hello
world
I think its originally creating a line break, but due to the object, it's not showing directly. Try to assign it in variable and access that in the console.
Code:
var v = {val:"test\ntest"};
console.log(v.val);
Output:
test
test

AngularJs $parse string to object

So lets say I have a server that returns a string like:
{
add:function(a,b) {
return a+b;
},
subtract:function(a,b) {
return a-b;
}
}
is it possible to $parse that into a function?
I tryed to parse it with:
$parse(element.Content) // Content is the string above
but get
Token '{' is an unexpected token
I would like something like:
elementFunctions = $parse(element.Content)
$parse does not do what you think it does!
To put it simply, it just resolves properties, by their name, against some context (angular scopes) -- basically.
Well, it's more than that, it provides a way to interact with these properties, but you'll get the gist of it by having a quick look at its documentation.
It does not evaluate Strings as javascript code.
You're most likely looking to evaluate your string.
Although in many, many cases there's a better, faster, more controllable and more reasonable solution!
const code = ''
+ 'const functions = {'
+ 'add: function(a,b) {'
+ 'return a+b;'
+ '},'
+ 'subtract: function(a,b) {'
+ 'return a-b;'
+ '}'
+ '};'
+ 'functions';
console.log(eval(code).add(50, 1));

How to invoke javascript in WebView Windows 10 UWP?

I am trying to load a javascript in WebView to do some calculations and get the output in a string. I tried to use following code
string htmlFragment = "<html><head><script type='text/javascript'>" +
"function doubleIt(incoming){ " +
" var intIncoming = parseInt(incoming, 10);" +
" var doubled = intIncoming * 2;" +
" document.body.style.fontSize= doubled.toString() + 'px';" +
" return doubled.toString());" +
"};" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
htmlView.NavigateToString(htmlFragment);
htmlView.LoadCompleted += async(s1,e1) =>
{
string result = await htmlView.InvokeScriptAsync("eval", new string[] { "doubleIt(25)" });
Debug.WriteLine(result);
};
Update
I am able to load simple javascript easily now based on help provided in the answer. But now I am facing issues when there is more than one function in javascript, I am getting an exception. I am trying the following code
string htmlFragment = #"<html><head><script type='text/javascript'>" +
"function a(){return 10;};" +
"function b(){return 20;};" +
"function c(){return 30;};" +
"return (a()*b()*c());" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
Please suggest.
The documentation for this feature is really poor. It took me some time to figure out how to invoke Javascript in UWP WebView
When you first look at the function call webView.InvokeScriptAsync(string,string[]) your initial reaction is that they want the function name as the first parameter and then the function paramaeters as the string array. (mainly because the MSDN documentation says this)
Parameters
scriptName
Type: System.String [.NET] | Platform::String [C++]
The name of the script function to invoke.
arguments
Type: System.String[]
[.NET] | Platform::Array [C++]
A string array that
packages arguments to the script function.
HOWEVER, this is wrong and will lead to hours of head banging. REALLY, what they want is the word "eval" in the first parameter and then a string array of functions, and or commands you wish to eval
var value = await webViewer.InvokeScriptAsync("eval",
new string[]
{
"functionName(functionParams)"
});
Having worked with Microsoft APIs for a few years now I am convinced that this is not the intended way of consuming this function and is a bit of a hack. Unfortunately if you want to consume JavaScript this is the only way that I know that works currently.
Anthony,
Try to check your own suggestion:
await webViewer.InvokeScriptAsync("eval",
new string[]
{
"functionName(functionParams)"
});
or:
await webViewer.InvokeScriptAsync(functionName, new string[]{ functionParameters });
The same as Microsoft suggests, just you are limiting a function name by one ("eval") - not necessary. Trust me, you can use any function name, as I am now with UWP and before with windows phone hybrid apps.
The question is already 4 years old, but I'm coming to see why you were getting an empty string as a result.
In your example, the functions in JavaScript return integers while the expected value is of type string.
By modifying these functions and returning a string like this:
string htmlFragment = #"<html><head><script type='text/javascript'>" +
"function a(){return '10';};" +
"function b(){return '20';};" +
"function c(){return '30';};" +
"</script></head><body>" +
"<div id = 'myDiv'>I AM CONTENT</div></body></html>";
We get the good result on the way back.

jQuery if condition doesn't return expected result

I am confused why the if condition not producing the result
Return result of fxresult value = " Call for price " this is not code and just for reference of variable result.
var fxresult = $(".price").html();
var fxRate = fxresult.replace(/ /g,"");
if (fxRate == 'Callforprice'){
alert("found")
}
may you use this regexp instead of yours.
var fxRate = fxresult.replace(/\s/g,"");
yours will work to but i think this one is a lil bit better because you avoid typos like one whitespace or two.
and you have a typo here
var fxresult value = " Call for price "
//---------------------------------------^
missing a ;
but your major problem in this line is
var fxresult value = " Call for price "
//----------^
you have a problem with the var declaration (variable names can't contain spaces)
see working FIDDLE

Why does eval() give undefined value in Javascript?

I am working in JavaScript coding. I have created a text area with name OQ_0 and value "0". When i use eval() method for that field in JavaScript it is giving the value undefined. The below are the part of JavaScript code
var tempOpenQtyStr = "document.InitiateReturnsForm.OQ" + "_" + 0;
var tempOpenxQtyStr = eval(tempOpenQtyStr).value;
alert('Manuals =' + document.InitiateReturnsForm.OQ_0.value);
alert('eval(tempOpenxQtyStr ) =' + eval(tempOpenxQtyStr));
alert('eval(tempOpenxQtyStr).value =' + eval(tempOpenxQtyStr).value);
Output:
Manuals = 0
eval(tempOpenxQtyStr ) = 0 --- Here it is suppose to show "[object]"
eval(tempOpenxQtyStr).value = undefined.
Kindly help me out what is change to do. Thanks in advance.
Why not just use document.InitiateReturnsForm["OQ_" + 0].value?
Try
alert('eval(tempOpenxQtyStr ) = ' + eval(tempOpenQtyStr));
alert('eval(tempOpenxQtyStr).value = ' + eval(tempOpenQtyStr).value);
In the second and third alert you are evaluating the second variable which stores the value of the first evaluated object. That's why the error occurs.
alert('eval(tempOpenxQtyStr ) =' + eval(tempOpenxQtyStr));
Since you put a string, not an object, inside tempOpenxQtyStr, it evaluates that string and returns 0.
alert('eval(tempOpenxQtyStr).value =' + eval(tempOpenxQtyStr).value);
Here you're using a method on a variable that contains a string. That doesn't work. It doesn't have that method, that's why it returns undefinied.
You might want to try doing eval(tempOpenxQtyStr.value) instead of eval(tempOpenxQtyStr).value since the last one does basically nothing, just evaluating an object and then fetching the objects value (it doesn't eval the value itself).

Categories