Node.js VM and string concatenation - javascript

I have an HTML file thats dynamically generated and only has a javascript object commented out. I'm trying to read that file, take the object out as a string, and run it with VM's runInNewContext(). But I run into a few hurdles.
Heres my code:
The file I have to read:
/*
{
"userId": ["2897599"],
"addressId": ["1287124"]
}
*/
The code I'm trying to use:
var startDataMap = body.indexOf('{')
, endDataMap = body.indexOf('}')
, dataMap = body.substring(startDataMap, endDataMap);
var sandbox = {};
try {
vm.runInNewContext(dataMap, sandbox)
} catch (error) {
console.log(error)
};
If I run this it'll kick back an error of:
[SyntaxError: Unexpected token :]
If I run it with a regex (ie with (/\{/) instead of ('{') ) it will execute without an error but it doesnt catch the data.
Question: Why will neither attempt work and how can I get the data I need using VM?
Update:
I took the advice of the answer below and it removed the error and added a tweak or two. Here is the updated code:
var startDataMap = body.indexOf('{')
, endDataMap = body.indexOf('*/', startDataMap)
, dataMap = body.substring(startDataMap, endDataMap);
var sandbox = {};
try {
vm.runInNewContext( '(' + dataMap + ')', sandbox)
} catch (error) {
console.log(error)
};
It removes the error but sandbox is still empty. I checked dataMap and it does have the required data but there is a line of whitespace at the end. Will this throw VM off? If so, how can I get rid of it, or do I need to alter my endDataMap ?

You likely need to add parentheses, so that the string is interpreted as an object instead of a block:
vm.runInNewContext("(" + dataMap + ")", sandbox)
Curly braces that are not in an expression are treated a blocks. By placing the code inside of parentheses, you make it clear that the code should be an object literal, rather than a block.

Related

I get: SyntaxError: missing ) after argument list, but I can't see anything missing

I have tried everything and noticed that the function will only work if I delete all arguments after #item.Host.
I occasionally get
SyntaxError: '' string literal contains an unescaped line break
if I try to tinker with arguments order:
<a href="#" onclick="sideBarMenu('#item.Type', '#item.TimeUtc.ToLongTimeString()', '#item.Host', '#item.Message', '#item.Source', '#item.User', '#item.AllXml')">
function sideBarMenu(type, time, host, message, source, user, xml) {
document.getElementById("sidebar2").style.right = ("-10px")
document.getElementById("side-bar-icon").classList.add("rotate")
document.getElementsByClassName("card-header")[0].innerHTML = type;
document.getElementsByClassName("time-for-logs")[0].innerHTML = time;
document.getElementsByClassName("card-host")[0].innerHTML = host;
document.getElementsByClassName("card-message")[0].innerHTML = message;
document.getElementsByClassName("card-source")[0].innerHTML = source;
document.getElementsByClassName("card-user")[0].innerHTML = user;
document.getElementsByClassName("card-text")[0].innerHTML = xml;
}
Code should pass all the values to the JS function without any error.
To solve my issue I had to use C# Utility to encode my JS
many of you have pointed my in to right direction, even that I haven't include a lot of code.
solution was to wrap my value like this:
'#HttpUtility.JavaScriptStringEncode(item.Type)'

define a long array in jquery click function

I have following long type session on server side code
long[] grouparray = ..;
Session["grouplist"] = grouparray;
Now I'm trying to get this session on View Page's jquery click function
$("#gpline").click(function () {
parseInt(#Session["grouplist"]);
var grouplistvalues = Session["grouplist"];
alert(grouplistvalues);
});
But this is having error once I debug using firebug
SyntaxError: expected expression, got ']'
parseInt(System.Int64[]);
You need to use Json.Encode and #Html.Raw on your c# data to make it compatible with your scripts.
Try this.
$("#gpline").click(function () {
var grouplistvalues = #Html.Raw(Json.Encode(Session["grouplist"])); // converting the session data into array of numbers in javascript variable
alert(JSON.stringify(grouplistvalues)); // stringify is used only to test.
});

Can't access module object properties from main in Screeps

I have the following simple test module (called testModule) in Screeps:
module.Exports = {
myProperty:'test'
};
In main, I try to output the contents of the module like so:
var x = require('testModule');
console.log("Value:" + JSON.stringify(x));
But all I get is an empty object ({});
As a result, x.myProperty is undefined. I have also tried making the module into a function, like so:
module.Exports = function(){
return {
myProperty:'test'
};
};
Then assigning it to x with var x = require('testModule')(); but I get the same result.
Obviously the game is still in development, so it is possible that this is a bug, but I'd like to rule out a mistake on my part first. Anyone been able to achieve what I'm trying to do? Anyone see what I'm doing wrong?
Edit
Interestingly, it gives me the same empty object even if I change the module to this:
module.Exports = 'test';
Surely this should be printing the string 'test' rather than an empty object? Is this a quirk of require js?
Just figured this out - I was using an uppercase E in module.exports. I have corrected the case and now it works fine:
module.exports = {
myProperty:'test'
};

Getting a Syntax/Parse error when using jQuery in Velocity

<script type="text/javascript>
(function($, win) {
function mySettingsInitJS () {
var self = this;
var opts = {
'params' : "userId=" + userId;
};
self.init = function() {
self.initUnlinkAction();
};
self.initbtnAction = function() {
$('#Btn').click(self.btnAction);
};
self.btnAction = function(e) {
if(e) { e.preventDefault(); }
jQuery.post(
'http://abc/rest/PostRequest',
opts.params, function(data) {
alert('This worked!');
}, "json");
};
}
function win.MyFilesSettingsInitJS = new MyFilesSettingsInitJS();
}(jQuery, window));
</script>
I have this this script in a velocity template page and a Btn also in it. Which is basically a fancy Link. I am also sure the rest API on the server side is working fine. But somehow my java script function is not called. Could some one please help me ?
Seems like you forgot quotes here:
'http://abc/rest/PostRequest'
It becomes pretty obvious with good syntax highlighting. Plus if you use JSLint or similar it will find most problems, as well as the console when debugging your code.
Your URL value needs to be a string...add quotes to it
You should use some developer tools available in the browser. Most browsers have at least an error console that would display any JS errors. For example, this code has several syntax errors:
In var opts = { 'params' : "userId=" + userId; }; it is illegal to end a line with ; when you're defining an object literal (a.k.a. map or dictionary).
Again at this line, where is userId defined? It is a bad practice to have global variables, so if userId is a global variable defined in another script, you should refactor the code
function win.MyFilesSettingsInitJS = new MyFilesSettingsInitJS(); is illegal, since you're adding a property to an object, you're not declaring a function or a variable. Just use win.MyFilesSettingsInitJS = new MyFilesSettingsInitJS();
Actually, that might be wrong as well, since above you defined mySettingsInitJS, not MyFilesSettingsInitJS (but that function could actually be defined somewhere else, I don't have the whole code)

Try Catch not catching syntax error in Chrome

I'm trying to troubleshoot a problem with someone else's JavaScript file, and they declared a function like the following.
function window.confirm(str) {
..... code here .....
}
This works fine with IE, but in Google Chrome, it throws an uncaught syntax error on the period in window.confirm. I tried to put a try catch around it like below, but that didn't work, same syntax error. It then won't let me use any functions defined in that JavaScript file.
try {
var window.confirm = function(str) {
..... code here .....
};
}
catch(e) {}
I also tried to change the declaration to a variable, like below, but that didn't work either. Same error.
var window.confirm = function(str) {
..... code here .....
};
Is there a way to catch this in Chrome?
function window.confirm(str) and var window.confirm ... are invalid. instead, try:
window.confirm = function(str){
..... code here .....
}
Two points :
try/catch are used to detect execution errors, not compilation ones. Don't deploy code with syntax errors.
function window.confirm(){ is a MS idiom you must avoid. You may use window.confirm = function() { or, if you're in the global scope, simply var confirm = function() {.
If you absolutely need to try and catch "Uncaught SyntaxError" errors, then you'll have to rely on JavaScript's hidden-under-the-floorboard misunderstood stepchild eval() function.
In the sample code below, obj will only be updated if the incoming string evaluates to a valid object; otherwise obj will default to {}. Let's assume $someTextField pulls in settings entered in a CMS textarea field, and the content editor has entered this malformed string in the field:
{
"foo": "bar
}
Sample code:
var oSettings = {};
// Returns "Uncaught SyntaxError: Unexpected token ILLEGAL(…)"
try {
oSettings = <?php echo $someTextField ?>;
} catch(e) {}
// This works
try {
eval('oSettings = <?php echo $someTextField ?>');
} catch(e) {}
Keep in mind that if the string to be evaluated is coming from some external source (e.g., CMS) and you have no control over it as in this example, then you'll need to do three things:
Detect and prevent execution of JavaScript code that could potentially wreck hell on your app.
Escape quotes in the incoming string to avoid conflicts with the JavaScript quotes. Since we're using PHP in this example, it would be better to do something like this:
eval('oSettings = <?php echo addslashes($someTextField) ?>');
Remove line breaks since the evaluated string needs to be on one single line. It would be even better to do something like this:
eval('oSettings = <?php echo addslashes(str_replace(array("\r\n", "\n", "\r"), "", $someTextField)) ?>');
You must fix the syntax errors. Try/catch will not catch syntax errors because syntax errors are compile time errors and try/catch can only catch runtime errors.

Categories