Unexpected token: u JSON.parse() issue - javascript

I have read online that the unexpected token u issue can come from using JSON.parse(). On my iPhone 5 there is no problem, but on my Nexus 7 I get this sequence of errors:
View large
I realize this is a duplicate, but I am not sure how to solve this for my specific problem. Here is where I implement JSON.parse()
$scope.fav = [];
if ($scope.fav !== 'undefined') {
$scope.fav = JSON.parse(localStorage["fav"]);
}

Base on your updated question the if condition does not make sense, because you set $scope.fav to [] right before, so it can never be "undefined".
Most likely you want to have your test that way:
if (typeof localStorage["fav"] !== "undefined") {
$scope.fav = JSON.parse(localStorage["fav"]);
}
As i don't know if there is a situation where localStorage["fav"] could contain the string "undefined" you probably also need test for this.
if (typeof localStorage["fav"] !== "undefined"
&& localStorage["fav"] !== "undefined") {
$scope.fav = JSON.parse(localStorage["fav"]);
}

One way to avoid the error (not really fixing it, but at least won't break):
$scope.fav = JSON.parse(localStorage["fav"] || '[]');
You're getting that error because localStorage["fav"] is undefined.
Try this and you'll understand all by yourself:
var a = undefined;
JSON.parse(a);

Unexpected token: u almost always stems from trying to parse a value that is undefined.
You can guard against that like this:
if (localStorage['fav']) {
$scope.fav = JSON.parse(localStorage['fav'];
}

In my case, the problem was I was getting the value as localStorage.getItem[key] whereas it should have been localStorage.getItem(key).
The rest and normally faced issues have been better explained already by the above answers.

Related

check if not undefined always evaluates to true

I have the following Javascript
var array = $('#calendar').fullCalendar('clientEvents');
var newArray = [];
array.forEach(function(entry) {
if (entry.description != undefined) {
newArray.push(entry);
}
});
I have an array filled with objects where some has a description and some does not - and I would like to filter out those that do not.
My problem is that the if-statement always evaluates to true no matter if description is undefined or not
As you can see from the screenshot - entry.description is undefined, but it still pushes it to the array.
What am I doing wrong?
Update
It seems to be working as intended with original code - after a firefox restart :S
I believe it might have been a firefox debugger issue.
Thank you all for you help anyway - feel free to comment on the actual code piece if you have anything to add though
Try this one:
if ( typeof entry.description != "undefined" ) {
//code if not undefined
}
try hasOwnProperty
if(entry.hasOwnProperty("description ")){
//you code
}

Logic behaves as if variable is NULL when it is not

I have a encountered a very strange error. I have:
externalContactsGrid.bind('dataBound', function(e) {
contactId = null;
if (typeof e.sender._data[0] === 'undefined') {
contactId = null;
} else {
contactId = e.sender._data[0].contactId
}
console.log(contactId)
if (contactId === false) {
alert(contactId)
$('#externalContactsGrid .k-grid-content table').html('<tr role="row" class="no-results"><td role="gridcell">No results found</td></tr>');
}
})
At the point of console.log(contactId) contactId is for example 2495, but when it hits the if it does not execute because apperently contactId is false (!). What could be causing this?
The weird thing is. is that the alert doesn't happen but the line after ($('#externalCon....) does.
The function is only executing once as I would see console log twice (i.e. 2495, and then null after it).
You are missing a semi-colon (a few, actually). Also, I think you're using the identity operator when you should be using the equality operator. If you want to compare values, use the equality operator.
http://www.w3schools.com/js/js_comparisons.asp
This seems to only happen when I use Jquery's .html() method. I have instead used .append() and the problem no longer occurs.

How can I suppress warnings for using '!!' (not not)?

In my project jshint complains about !! I need to convert a string to a boolean value
var x = 'true';
if ( !!x === true ) { ... }
So, jshint throws the following problem:
line 35 col 20 Confusing use of '!'.
What jshint-option should I disable to allow this? Or is that not possible?
It looks like the problem is with ===. Simply
if (!!x )
works fine.
I think the "confusing" part is that !!foo === bar is hard to parse priority-wise (is it (!!foo)==bar or !(!foo==bar)?).
This particular "feature" has caused so much pain in the community.
You can disable it by putting this in your .jshintrc config file.
{
"-W018": true
}
WARNING: this is not going to evaluate the way you want it to
var myBool = Boolean("false"); // == true
var myBool = !!"false"; // == true
if you don't want jshint to yell at you, also you don't need to have === when comparing bool == is the same. though if you are making a bool value you should not need to compare it at all.
if(myBool)
{
//some code here
}
or
if(!myBool)
{
//some code here
}
to get the value as a bool you prob want to just do a string comparison
var mybool = aString == "true";
that should get you what you are looking for then you can just:
if(myBool)
{
//some code here
}
To really answer this question, not providing workarounds, disabling this error in jshint can be done by
-W018

does object/array exist in javascript

I'm trying to put content from RSS feed - problem is every RSS feed has different formats for images, content etc.
I'm trying to see if certain object exists in javascript or jquery:
item.mediaGroups[0].contents[0].url
How can I check it in an if statement? I keep getting for feeds without this structure:
Uncaught TypeError: Cannot read property '0' of undefined
Also tried:
if (typeof item.mediaGroups[0].contents[0].url === "undefined")
but I keep getting the same error.
thanks!
There is no "simple" built in way to do this sort of in depth checking. The reasoning is simple - most of the time you know the type of the objects you're working against.
You can do:
if (typeof item !== "undefined" &&
typeof item.mediaGroups !== "undefined" &&
typeof item.mediaGroups[0] !== "undefined" &&
typeof item.megiaGroups[0].contents !== "undefined" &&
typeof item.megiaGroups[0].contents[0] !== "undefined" &&
typeof item.mediaGroups[0].contents[0].url !== "undefined"){
When you type all that you might want to consider your data structures, since this really is not a situation you should be in to begin with :)
(hint, you can skip the typeof on all but the first, but I think typeof is a good clarification here).
The real question is this:
Why are you not sure what the structure of your data is?
If you are querying data (for example XML in an RSS feed) there are effective ways to do so with XPATH or query selectors. Object property access is built for objects where what you're querying is a document. Sure, it's possible with a bunch of ugly checks just like you can hammer a nail in with a heavy screwdriver.
You can see this question in Stack Overflow on how to use DOM methods to parse XML.
If you're uncertain about the exisence of properties, try this helper function:
function getProperty(root) {
var l = arguments.length, i, undefined;
for( i=1; i<l; i++) {
if( typeof root[arguments[i]] == "undefined") return undefined;
root = root[arguments[i]];
}
return root;
}
You can then call it like this:
var url = getProperty(item,'mediaGroups',0,'contents',0,'url');
As a more "haxy" way, you can try this:
try {url = item.mediaGroups[0].contents[0].url;}
catch(e) {url = undefined;}
I would check the length of both arrays in this case to be sure - before assuming there are objects defined at index 0
item.mediaGroups.length > 0
and
item.mediaGroups[0].contents.length > 0
As the outer check you can also throw in a
if(item.mediaGroups){
}
How about 'optional chaining' (described in ES2021 spec and already implemented in all browsers except three) ?
from MDN:
The optional chaining operator provides a way to simplify accessing
values through connected objects when it's possible that a reference
or function may be undefined or null.
The optional chaining ?. stops the evaluation if the value before ?. is undefined or null and returns undefined so it is giving us a way to handle the possibly undefined/nullsish values
item?.mediaGroups[0]?.contents[0]?.url // will evaluates to undefined if either of those is undefined.
item.mediaGroups[0].contents is undefined, you have to check for it.
if(item.mediaGroups && item.mediaGroups[0].contents) {
return item.mediaGroups[0].contents[0].url;
}
It's not a solution with if-statements (as requested), but you can use exceptions to achieve similar functionality. Something like this:
function throwOrReturn(thing){
if(typeof thing === 'undefined'){
throw "Didn't find it..."
}else{
return thing
}
}
// The unknown thing.
var a = {
b1: {
},
b2: {
c: 'lookingFor'
}
}
var c
// Test our different paths.
try{
// First guess.
c = throwOrReturn(a.b1.c.d)+" - a.b1.c.d"
}catch(error){
try{
// Second guess.
c = throwOrReturn(a.b[45][34].c)+" - a.b[45][34].c"
}catch(error){
try{
// Third guess.
c = throwOrReturn(a.b2.c)+" - a.b2.c"
}catch(error){
// Try more guesses, or give up.
c = "notFound"
}
}
}
console.log("c:", c) // Logs: "c: lookingFor - a.b2.c"
It ain't pretty, but it's an alternative worth to mention.

How can I speed up this bit of JSON date parsing?

I am stuck using an AJAX library from about 5 years ago in this project, and it had some issues with parsing dates in JSON. I wound up rewriting its parse function to use a single regex:
return eval('(' + (enableDateParsing ? text.replace(/"(?:\\)?\/Date\((.*?)\)(?:\\)?\/"/g, "new Date($1)") : text) + ')');
This works really well, but I thought I could get a speed up if I used native JSON parsing in IE8 / chrome / ff, so I added this bit:
if (typeof JSON !== 'undefined' && typeof JSON.parse !== 'undefined') {
var nativeJsonDateParseRegex = /\/Date\(.*?\)\//g;
return JSON.parse(text, function (key, value) {
if (AjaxPro.enableDateParsing && typeof value === 'string' && value.match(nativeJsonDateParseRegex))
{
value = new Date(parseInt(value.substr(6)));
}
return value;
});
}
else // revert to eval for ie6/ie7
The reviver callback will execute once for each JSON property returned, so it has to be very fast. During a profile I've seen it's been called 170484 times, but still runs pretty fast (131.237ms). Any ideas on how to make it faster, or is this the best you can do without serious tweaking?
Your code contains a lot of constant conditions, you'll be fine with checking once whether native JSON is supported or not.
Suggestions:
check for native JSPN support at page load, and add the right function accordingly.
Drop the global flag from the regex if you do not need it
Drop regular expressions if possible, if every date always starts with "/Date(", search for it. It's much faster (see benchmark at jsperf.com)
todo: check whether parseInt can be replaced with an other method to get rid of the trailing )/.
If AjaxPro.enableDateParsing is a constant, you can remove if from AjaxPro.jsonParse and and make it a condition like the check for native JSON
Code without RE:
if (typeof JSON !== 'undefined' && typeof JSON.parse !== 'undefined') {
AjaxPro.nativeJsonDateParseRegex = /\/Date\(.*?\)\//g;
AjaxPro.dateFunc = function(key, value) {
if (typeof value === "string" && !value.indexOf("/Date(")) {
return new Date(value.substring(6, value.length-2));
}
return value;
};
AjaxPro.jsonParse = function(text) {
if (AjaxPro.enableDateParsing) {
return JSON.parse(text, AjaxPro.dateFunc);
}
return JSON.parse(text);
};
} else // revert to eval for ie6/ie7
This should be highly optimized. You might want to run some more test on your own in multiple browsers. Maybe checking for a property of a string is faster than checking its type (doubt it), thing like that.
One not so good microoptimization, but still worth giving a try.
Since your substring contains millisecond timestamp only, and no other garbage string.
You can remove the call to parseInt.
You can try typecasting with simple mathematical operation like multiplication with 1.
Might save some time if you are too keen on microoptimizations.
value = new Date(1*(value.substr(6)));
example:
a = "a:3333";
b = a.substring(2);
alert(b*2); // alerts 6666

Categories

Resources