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.
Related
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)'
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.
<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)
I can't see a clear mistake in this code. Instead of validating my fields, it just tries to send my form and I don't know why.
This is my jsFiddle: http://jsfiddle.net/PAALA/
Other question, how to validate if select box was picked?
Firstly, because of how JSFiddle works, defining a function with function foo() {...} is unreliable. Instead, use foo = function() {...} syntax.
Next, you have an error in your script when you try to access document.forms["bug_form"]["Project"].value - there is no text input with that name.
Finally, to prevent accidental submission, do this:
validateBugForm = function() {
try {
// ALL YOUR ORIGINAL CODE HERE
}
catch(e) {
alert("An error occurred: "+e);
return false;
}
}
This will ensure that false is returned, even if your code errs.
The Javascript code is crashing out on the third line when you try to get the value for "Project". Looks like you forgot to give that one a name.
So, I've created a function to do some error checking on an XML file that I recieve from an AJAX call. Part of the validation is that the function then builds out an object for easy access while I process that data into a form. In FF, works like a charm. IE dies with the error:
Object doesn't support this property or method
Here is the function (minus the un-important bits):
function checkReceiveXMLTagString( doc, messageObject, tag ) {
var tag_nodes = doc.getElementsByTagName( tag );
...do some error checking...
messageObject[tag] = tag_str; <-- error occurs on this line
return true;
}
Here is an example of how the function is call:
if ( checkReceiveXMLTagString( messageObject.Name[0], messageObject.Name[0], "First" ) ) {
...process messageObject.Name[0].First...
}
Like I said, FF has no issues. Safari loads the pages as well. IE has issues.
Thanks!
Looks like something is making messageObject be null or undefined
If the error is on this line:
messageObject[tag] = tag_str;
Then, the only two ways I know of that that can cause an error are:
messageObject is not an object that you can set properties on (null or undefined are the most likely ways that would happen)
tag is null or undefined
Since I see that your code calls this function hundreds of times so you can't effectively just break on it, I'd suggest you put in some defensive coding to check for those conditions and output something to the debug console to identify what the state is when the problem occurs. You can even trigger a conditional breakpoint with code like this:
if (!messageObject || !tag) {
debugger;
}
In the toughest cases, you can put an exception handler around it and break when the exception is thrown:
try {
messageObject[tag] = tag_str;
} catch(e) {
debugger;
}
Both of these will allow you to capture the condition in the debugger and examine all your parameters at the time of the error.