2

I have some javascript that hasn't changed in over a year and suddenly it's breaking. So my first thought is it must be data related. In looking at the data, it looks like the structure hasn't change in over a year. Been running fine for a long time and suddenly it's breaking.

Here is my js, populating an array with some JSON:

var history = [{BillingCycleHistoryID: 339, BillingCycleDate: '7/18/2014', StartTime: '7/18/2014', PercentComplete: 100, EndTime: '7/18/2014', HoursRan: 0.16, StartedBy: 'ADMIN'}];

Chrome developer toolbar reports this error: "Uncaught type error: Cannot read property BillingCycleHistoryID of undefined." That error gets triggered on the line with "value.BillingCycleHistoryID" below...

if (typeof history != 'undefined') {
   $.each(history, function (key, value) {
      tbl.append(
        '<tr data-history-id="' + value.BillingCycleHistoryID + '">' +
        ....[more down here]

When I paste the json into jsonlint, it throws an error that makes no sense to me:

Parse error on line 2:
[    {        BillingCycleHistoryI
--------------^
Expecting 'STRING', '}'

enter image description here

Any idea what is going on here?

HerrimanCoder
  • 6,835
  • 24
  • 78
  • 158
  • var history = [{BillingCycleHistoryID: 339, BillingCycleDate: '7/18/2014', StartTime: '7/18/2014', PercentComplete: 100, EndTime: '7/18/2014', HoursRan: 0.16, StartedBy: 'ADMIN'}]; That is array. ==>>> var history = [{"BillingCycleHistoryID": 339,....... This is JSON – Lex Nguyen Jul 22 '14 at 01:04
  • @Tom Actually the names of the properties need to be double quoted – adaam Jul 22 '14 at 01:06
  • But my wannabe json has been constructed this way for over a year and it never broke the js before. Nothing has changed in the code. Why would it throw the error suddenly? – HerrimanCoder Jul 22 '14 at 01:07
  • I executed your line **var history = ...** it shows me **History {state: null, length: 1, back: function, forward: function, g**, it means **History** is a reserved variable. My Browser - Chrome – Harpreet Singh Jul 22 '14 at 01:10
  • Maybe your history data has been changed, because i can not see in your picture. – Lex Nguyen Jul 22 '14 at 01:12
  • Harpreet, you are right!!! I changed the "history" var name and it all works now. I'm sure my json is not technically correct, but that had nothing to do with the error. If you can post your answer I can accept it. Please do, because the existing suggested answers don't solve it. WTF, this code has been the same way forever! – HerrimanCoder Jul 22 '14 at 01:17
  • @SweatCoder Have you recently moved your code from within any function? – Harpreet Singh Jul 22 '14 at 01:40

4 Answers4

2

Your code is valid javascript, just not strictly valid JSON as others have pointed out.

In your screenshot the history variable doesn't look as it should (it should have length 1). You probably just need to rename it: 'history' appears to be a global variable which Chrome controls. If Chrome has added this behaviour recently that would explain why your code suddenly broke.

See http://www.javascripter.net/faq/reserved.htm

'history' is not strictly speaking a reserved word, but it's still best avoided as a global variable name. (And using global variables isn't wise if you can avoid it anyway.)

swilson
  • 471
  • 4
  • 9
  • You are absolutely right...don't remember upgrading my Chrome recently, maybe it happened automatically. I guarantee "history" was not a reserved keyword last week in Chrome, but now it is. Anyway...Harpeet suggested the right answer first. If he posts that, I'll aceept. Otherwise I'll accept yours. Back in an hour. – HerrimanCoder Jul 22 '14 at 01:20
  • 2
    @SweatCoder `history` is *not* a reserved word. Yesterday, or today. – user2864740 Jul 22 '14 at 01:29
  • user2864740: what world do you live in? When I changed my variable from "history" to another word, everything worked perfectly again. Also you can see from swilson's link that "history" is a "predefined names of implementation-dependent JavaScript objects, methods, or properties". Maybe you're playing semantics, but it's useless and you just waste time. – HerrimanCoder Jul 22 '14 at 01:38
  • Reserved word or not, a simple experiment will demonstrate that naming a variable 'history' does not work in Chrome. It does work in jsfiddle and probably most other javascript implementations, as @pixelchild first pointed out with http://jsfiddle.net/z5rUw/1/ – swilson Jul 22 '14 at 01:49
  • @SweatCoder I live in the world of [defined rules](http://www.javascripter.net/faq/reserved.htm). It is reserved or it is not reserved - it's not reserved. – user2864740 Jul 22 '14 at 01:50
  • 1
    @swilson It works fine to name a *variable* `history`. However, it is not [reliably] possible to re-assign to *global variables*, including history. `var` outside of a function does not introduce a new variable. The bigger problem is thus not correctly using a module/IIFE pattern. – user2864740 Jul 22 '14 at 01:51
  • @user2864740 that's true, there is only a problem if 'history' is a global variable. – swilson Jul 22 '14 at 02:07
  • @SweatCoder, **user2864740** is right check this code - **function test() { var history = 'myVar' console.log('inside function: ',history) } test() console.log('outside function', history) //output //myVar //History {state: null, length: 1, back: function, forward: function, go: function…** – Harpreet Singh Jul 22 '14 at 02:23
  • Related: [Using the variable “name” doesn't work with a JS object](http://stackoverflow.com/q/10523701/4642212). – Sebastian Simon Jun 14 '16 at 17:25
1

jsonlint error comes from you not enclosing your keys in quotes. This will work properly but jsonlint doesn't like it. You can see this from the FAQ here: http://jsonlint.com/#

Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['

You probably have an extra comma at the end of your list. Something like: [ "a", "b", ] You also may have not enclosed your collection keys in quotes. Proper format for a collection is: { "key": "value" }

Community
  • 1
  • 1
cnaut
  • 144
  • 1
  • 12
0

strings and vars should be in double quotes try this:

[
    {
        "BillingCycleHistoryID": 339,
        "BillingCycleDate": "7/18/2014",
        "StartTime": "7/18/2014",
        "PercentComplete": 100,
        "EndTime": "7/18/2014",
        "HoursRan": 0.16,
        "StartedBy": "ADMIN"
    }
]
herriekrekel
  • 571
  • 6
  • 15
0

I think you are confused with what JSON is, your example is not using JSON at all.

If you are using JSON you would have something like (If using jQuery)

var history = $.parseJSON("<<json string here>>");

Your example is simply declaring a variable (history) that consists of a native javascript array with one anonymous native javascript object. I'm assuming your printing that variable to the page from some back end code?

However your code looks correct, i have an working example here

http://jsfiddle.net/z5rUw/1/

jennas
  • 2,444
  • 2
  • 25
  • 31