I'm trying to have an if statement. The problem is that I'm trying to grab a url parameter that may or may not be there. When I plug it into my JavaScript it throws an error because sometimes the variable isn't there so the syntax is incorrect. Here's what I mean:
var manual = {module_url,manual};
if(manual)
$('#manual').show();
Now if the url parameter is present the code ends up looking like this:
var manual = true;
if(manual)
$('#manual').show();
If it is not, then the code ends up looking like this:
var manual = ;
if(manual)
$('#manual').show();
That's where my problem lies. It ends up breaking all the JavaScript on the rest of the page. I tried using a try/catch but the problem still happens because of the syntax. Unfortunately, I don't have control of the server aspect so I got to work with what I have.
You can't catch or recover from a syntax error.
The solution in this case is to manipulate the code so that it's valid even if the value inserted by the template is empty.
var manual = ("{module_url,manual}" !== "");
When {module_url,manual} is empty, the above line becomes "" !== "" which evaluates to false.
Related
When developing React app should we check every property if exists to make sure our app does not crash? I currently have for ex something like below:
<h3>{block && block.box && block.box.title}</h3>
but I wonder if I should do it like this:
<h3>{block && block.box && block.box.title && block.box.title}</h3>
to make sure block.box.title exists before accessing it!
Any idea how can i handle these things in javascript in general, this approach seems kinda verbose to me.
UPDATE, should this check be enough:
<h3>{block.box.title && block.box.title}</h3>
In this example, I think it's safe to assume that block exists, otherwise your code is probally incorrectly written, so that check isn't needed.
Then, the double title makes no sense. The syntax you're using (and most people) is a bit of a cheat, it effectivly does this:
isset(block) && isset(block.box) && echo(block.box.title)===true
This makes use of the fact that a string is considered true and that javascript parses from left to right.
It evaluates/runs the 1st part: run the ISSET, continue the checks if that's true
It evaluates/runs the 2nd part: run the ISSET, continue the checks if that's true
...
It evaluates/runs the last part: Echo the output, continue the checks if it's true.
At the last point, it has already output the string, then it evaluates the outcome. If the string hasn't been output (it's empty or it doesnt exists) that will return false.
Response to your update: No that wont work. It will try to access the title property of null if box doesn't exist, which results in an error,
New js feature here:
<h3>{block?.box?.title}</h3>
I was reviewing some code and I saw something like this:
if (result.indexOf('?') === -1) {
result += '?';
}
result += '&' + SOMETHING;
Clearly this can result in an URL like this http://example.com?&a=b
The author of the code sees nothing unusual in the code but ?& bothers me. I could not find any restrictions in the RFC for URI to prove him wrong (or maybe I missed it).
Clearly in the network tab of Chrome dev tools it appears as an empty pair:
Should URL like this bother me or am i just paranoid?
This case will be interpreted as an empty value by most servers, so yes, it is indeed valid. What's going to happen is that the server checks between ? and every & and then separates the values at = accordingly.
So when there is nothing between a ? and a & (or two &'s), the values will both be empty. Missing ='s will affect whether the value is "" or null, but it will not make the query invalid.
Watch out with this, because some parsers might not find this to be valid, so you may get problems when using custom parsers (in JavaScript for example).
I wrote up a blog post about some of these edge cases years ago.
tl;dr: yes, ?&example is valid
What's important about it is that you're defining a key of "" with a value of null.
You can pretty much guarantee that almost no libraries support those empty string keys, so don't rely on them working, but as far as having a URL along the lines of ?&foo=bar, you should be fine when accessing the foo key.
I have the following javascript which works fine for the most part. It gets the user that has logged in to the site and returns their DOMAIN\username info. The problem arises when the username starts with a letter that completes a valid escape character (eg. DOMAIN\fname). The \f gets interpolated and all kinds of terrible things happen. I have tried every sort of workaround to try and replace and/or escape/encode the '\'. The problem is the \f does not seem like it is available to process/match against. The string that gets operated on is 'DOMAINname'
// DOMAIN\myusername - this works fine
// DOMAIN\fusername - fails
var userName='<%= Request.ServerVariables("LOGON_USER")%>';
userName = userName.replace('DOMAIN','');
alert("Username: " + userName);
I also see all kinds of weird behaviour if I try to do a workaround using the userName variable, I think this may be because it contains a hidden \f. I've searched high and low for a solution, can't find a thing. Tried to find out if I could remove the DOMAIN\ on the serverside but that doesn't seem available either. Does anyone have a solution or workaround? In the debugger, the initial value of the servervariable is correct but the next immediate call to that variable is wrong. So the interpolated values in the debugger look like this:
var userName='DOMAIN\fusername';
userName; // 'DOMAINusername' in debugger.
Thanks
If you're using ASP.net (as it looks like you are), use AjaxHelper.JavaScriptStringEncode or HttpUtility.JavaScriptStringEncode to output the string correctly.
var userName='<%= HttpUtility.JavaScriptStringEncode(Request.ServerVariables("LOGON_USER"))%>';
I'm clueless.
In my Jquery Mobile Plugin I'm declaring:
var $currentEntry = $.mobile.urlHistory.stack[$.mobile.urlHistory.activeIndex].url;
$activePage = $('div:jqmData(url="'+ $currentEntry +'")');
So I'm taking the active page's url and use it to construct an $activePage object.
This works fine on desktop, but on my iPad (iOS3.3), $currentEntry is defined correctly, but $activePage is undefined.
Question:
What can be reasons for this?
You can rule out race conditions, because wrapping this in a 10sec timeout still produces the same result. Also, if I console the respective page directly and query it's data-url, it shows the correct value. So how come the above still gives me undefined on iOS
undefined
while working correctly everywhere else?
Thanks for any hints!
EDIT:
The element will be dynamic, but I can console for the page in my setup directly like so:
console.log( $('div:jqmData(wrapper="true").ui-page-active').attr('id') );
console.log( $('div:jqmData(wrapper="true").ui-page-active').attr('data-url') );
Both return the correct id and data-url, so the elements must exist.
EDIT2:
I can query for the attribute data-url which gives me the correct value. However, I cannot select using this attribute like so:
$('div[data-url="'+$currentEntry+'"]').length
which gives me 0
I am going to admit that I am blind-guessing, but you should try:
$activePage = $('div').filter(function(){return $(this).jqmData('url') === $currentEntry})
BTW, just for semantics i think "$currentEntry" shouldn't start with a dollar sign if it is not a jQuery object.
I'm trying to re-write the URLs of a set of links that I select using a jQuery class selector. However, I only wish to re-write the links that don't already have a href attribute specified, so I put in an if/else construct to check for this... However, it's not working. It does work without the if else statement so I'm pretty sure that is where I screwed up. I'm new to both JavaScript and jQuery so sorry if my question is elementary and/or overly obvious.
var url = window.location;
var barTwitter = $("a.shareTwitter").attr('href');
if (barTwitter).val() == "null") {
$("a.barTwitter").attr('href','http://www.twitter.com/home?status='+ url +'');
} else {
$("a.barTwitter").attr('href',barTwitter);
}
if (barTwitter).val() == "null") {
This is syntactically invalid (count the parentheses!). You rather want to do:
if (barTwitter.val() == "null") {
Further, the val() function only works on input elements which are wrapped by jQuery, not on element attribute values which are at end just normal variables. You rather want to compare normal variables against the literal null:
if (barTwitter == null) {
There are actually a few problems with your code... BalusC correctly describes the first one - syntax errors in your if condition - but you should probably consider some of the rest...
I'll start with your code corrected according to BalusC's answer, with comments added to describe what's happening:
var url = window.location; // obtain the URL of the current document
// select the href attribute of the first <a> element with a shareTwitter class
var barTwitter = $("a.shareTwitter").attr('href');
if (barTwitter == null) { // if that attribute was not specified,
// set the attribute of every matching element to a combination of a fixed URL
// and the window location
$("a.barTwitter").attr('href','http://www.twitter.com/home?status='+ url +'');
} else {
// set the attribute of every matching element to that of the first
// matching element
$("a.barTwitter").attr('href',barTwitter);
}
Other issues with your code
Ok... now the problems:
jQuery matches sets - a single selector can potentially match multiple elements. So if there are multiple links on the page with the shareTwitter class, you'll be pulling the href attribute for the first one, but changing all of them. That's probably not what you want, although if there is only a single link with that class then you don't care.
In the else clause, you're not actually modifying the href at all... Unless you have multiple matching links, in which case you'll change all of them such that they have the href of the first one. Again, probably not what you want, although irrelevant if there is only one link... So, in the best-case scenario, the else clause is pointless and could be omitted.
You can actually omit the if/else construct entirely: jQuery allows you to test for the existence of attributes in the selector itself!
You're including the URL of the current page in the querystring of your new, custom URL - however, you're not properly escaping that URL... This could cause problems, as full URLs generally contain characters that are not strictly valid as part of URL querystrings.
Notes on working with JavaScript
A quick aside: if you plan on doing any development using JavaScript, you should obtain some tools. At minimum, install Firebug and familiarize yourself with the use of that and JSLint. The former will inform you of errors when the browser fails to parse or execute your code (in addition to many, many other useful debugging and development tasks), and the latter will check your code for syntax and common style errors: in this case, both tools would have quickly informed you of the initial problems with your code. Instructing you in the proper use of these tools is beyond the scope of this answer, but trust me - you owe it to yourself to take at least a few hours to read up on and play with them.
Toward safer code
Ok, back to the task at hand... Here's how I would re-write your code:
var url = window.location; // obtain the URL of the current document
// escape URL for use in a querystring
url = encodeURIComponent(url);
// select all <a> elements with a shareTwitter class and no href attribute
var twitterLinks = $("a.shareTwitter:not([href])");
// update each selected link with a new, custom link
twitterLinks.attr('href', 'http://www.twitter.com/home?status='+ url +'');
Note that even though this new code accomplishes the same task, it does so while avoiding several potential problems and remaining concise. This is the beauty of jQuery...
firs of all your syntax is screwed up: if (barTwitter).val() == "null") should be if (barTwitter.val() == "null") or if ((barTwitter).val() == "null")
Secondly barTwitter is either going to be a string or null so you cant call val which is a jQuery Object method specific to input elements.
Lastly you probably dont want to compare to null because it possible the value will be an empty string. Thus its better to use length property or some other method. A sample with lenght is below.. but im not sure what attr returns if if ther eis no value... check the docs.
var url = window.location;
var barTwitter = $("a.shareTwitter").attr('href');
if (barTwitter.length < 1) {
$("a.barTwitter").attr('href','http://www.twitter.com/home?status='+ url +'');
} else {
$("a.barTwitter").attr('href',barTwitter);
}