-1

I am trying to parse out all keys from a json data.

<script type="text/javascript">
    $(document).ready(function () {
        $.ajax({
            type: "POST",
            url: "History.aspx/GetFTEData",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            success: function (data) {
                var returnedstring = data.d;
                var colHeader = Object.keys(data[0]); <---- error line

            }
        });
    });
</script>

However, var colHeader = Object.keys(data[0]); this doesn't work while running it with my IDE (VS2015) on my IE 11 or Firefox browser even though it works in the jsfiddle example:-

https://jsfiddle.net/qpu3cn5u/

The error message:- 0x800a138f - JavaScript runtime error: Object.keys: argument is not an Object

What alternatives do I have? such that I can only parse the keys out as column names for an html table that I am trying to populate with values.

example of data:-

var data = `[{"Customer Name":"XXXX","1999":76.000,"2000":68.000,"2001":49.000,"2002":41.000,"2003":47.000,"2004":56.000,"2005":33.000,"2006":51.000,"2007":56.000,"2008":52.000,"2009":55.000,"2010":52.000,"2011":57.000,"2012":55.000,"2013":93.000,"2014":92.000,"2015":62.000,"2016":71.833},{"Customer Name":"YYYYY","1999":29.000,"2000":27.000,"2001":35.000,"2002":37.000,"2003":32.000,"2004":29.000,"2005":44.000,"2006":49.000,"2007":69.000,"2008":109.000,"2009":108.000,"2010":150.000,"2011":189.000,"2012":215.000,"2013":53.000,"2014":78.000,"2015":65.000,"2016":63.000},{"Customer Name":"ZZZZ","1999":0.000,"2000":0.000,"2001":0.000,"2002":0.000,"2003":0.000,"2004":0.000,"2005":0.000,"2006":0.000,"2007":0.000,"2008":0.000,"2009":0.000,"2010":0.000,"2011":0.000,"2012":28.000,"2013":36.000,"2014":59.000,"2015":90.000,"2016":94.000},{"Customer Name":"AAAAA","1999":0.000,"2000":0.000,"2001":0.000,"2002":0.000,"2003":0.000,"2004":0.000,"2005":0.000,"2006":0.000,"2007":0.000,"2008":0.000,"2009":0.000,"2010":0.000,"2011":0.000,"2012":18.000,"2013":18.000,"2014":18.000,"2015":19.000,"2016":18.000}]`
Philo
  • 1,931
  • 12
  • 39
  • 77
  • 1
    The linked jsfiddle has code that has nothing at all to do with the code you posted here. – Pointy Aug 28 '17 at 20:58
  • Can you put an example fo what `data` contains ? (there should be no problem from `Object.keys()` : https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Object/keys ) – Seblor Aug 28 '17 at 20:58
  • Firefox has no problem with `Object.keys` and your jsfiddle there works great – Dekel Aug 28 '17 at 20:59
  • added an example of my data – Philo Aug 28 '17 at 21:00
  • @Dekel yes it works on jsfiddle but not on my VS2015 – Philo Aug 28 '17 at 21:00
  • 1
    how vs2015 is related to firefox? – Dekel Aug 28 '17 at 21:01
  • no but VS is running the code with IE and Firefox. – Philo Aug 28 '17 at 21:02
  • I don't know what kind of dependency difference VS vs JSfiddle will have. – Philo Aug 28 '17 at 21:02
  • What do you mean "doesn't work in VS"? VS and JSfiddle aren't comparable... one is an IDE and the other is a website. – Tyler Roper Aug 28 '17 at 21:04
  • @Santi 0x800a138f - JavaScript runtime error: Object.keys: argument is not an Object -- error message on my IDE run. no error via JS. – Philo Aug 28 '17 at 21:07
  • and yes I understand the difference between JSfiddle and VS. can we not get stuck on semantics? thank you. – Philo Aug 28 '17 at 21:08
  • @Philo: Then that's telling you the issue. Whatever you're passing is not an object. All you're missing is a little debugging effort using `console.log()`. – spanky Aug 28 '17 at 21:09
  • Semantics are actually pretty crucial when describing a problem. – spanky Aug 28 '17 at 21:09
  • I am sort of surprised how its not an object.... I basically posted my example object as data in the jsfiddle – Philo Aug 28 '17 at 21:09
  • @spanky semantics are important.. but in this specific case the jsfiddle vs VS semantics is not important. – Philo Aug 28 '17 at 21:10
  • @Philo: Actually it is. It's quite confusing where exactly the problem is. Anyway, you posted some `$.ajax` code in your question. I don't know how this relates to the other code, but I'll go out on a limb and guess that you're fetching some data but then trying to use that data *outside* the `$.ajax` callback, so it doesn't exist yet. You really need to provide a complete example directly in your question. – spanky Aug 28 '17 at 21:12
  • @spanky I am using it inside of the ajax callback. I provided the extra line that I had separated in my question. – Philo Aug 28 '17 at 21:13
  • You have both `data.d` and `data[0]` in your callback. So what is the response actually sending, an object or array structure? Are you sure you don't need `Object.keys(data.d[0]);` – spanky Aug 28 '17 at 21:21
  • ...or maybe this? `Object.keys(data.d)[0]` – spanky Aug 28 '17 at 21:24
  • @spanky neither worked. I tried those combos before. – Philo Aug 28 '17 at 21:32

2 Answers2

1

It seems the problem is that the data[0] is still in its JSON state. This often happens when you encode individual objects, and then encode their enclosing array. The individual objects get double-encoded.

As a test, try this:

var parsed = JSON.parse(data[0]);
console.log(Object.keys(parsed));

If this shows the result that you wanted, then that tells you the double-encoding is the problem.

However, parsing it again is not the solution. You need to fix this on the server that's generating the JSON data so that it doesn't get double-encoded.

spanky
  • 2,768
  • 8
  • 9
  • This worked instead... had used it many moons ago....var jsondata = $.parseJSON(data.d) – Philo Aug 28 '17 at 22:24
  • @Philo: I don't understand where this `.d` property is coming from. Based on the info you gave us, `data` is an Array. In any case, pretty sure there are some encoding issues on the server you need to fix. – spanky Aug 28 '17 at 22:26
  • good points. also now my columnheaders are just - 0 1 2 3 4... lol. I haven't solved the issue. but Object.keys is not throwing an error. – Philo Aug 28 '17 at 22:31
  • Then `data.d` is pointing to your array, as I suspected above. So `Object.keys(jsondata[0]);` – spanky Aug 28 '17 at 22:35
  • indeed. you have been very helpful. I re-learned some things that I had forgotten. thank you. Only thing, my customer name column is somehow parsed at the end...all the years show up and then customer name.. even tho customer name is the first key in my data. – Philo Aug 28 '17 at 22:38
  • 1
    @Philo: You can't really rely on the order of keys in an object, even when using `Object.keys`. I would manually put the customer name in first, remove it from the object, sort the years, and then add those. However you do it, you need to find a way to guarantee the order manually. – spanky Aug 28 '17 at 22:49
  • @spanky (+1) for spotting the problem and providing the solution – Christos Aug 29 '17 at 04:39
0

If you have to support older browsers you can always try and find examples of how to perform similar tasks using older styles/APIs. For example you can loop over JavaScrip object props by doing something like this:

for (var property in object) {
    if (object.hasOwnProperty(property)) {
        // do stuff
    }
}

Similar question/code example found here.

However, Object.keys() is support is all major browsers. Including IE11, reference here.

stetson
  • 145
  • 2
  • 11
  • Then how does my jsfiddle work with the same data returned to my JS object... and Visual studio finds an error ?? https://jsfiddle.net/qpu3cn5u/2/ – Philo Aug 28 '17 at 21:12
  • 0x800a138f - JavaScript runtime error: Object.keys: argument is not an Object – Philo Aug 28 '17 at 21:15
  • I'm not sure why VS would be throwing that error. However, here is an example of something you can try to see if it resolves your issue. https://jsfiddle.net/88315f9e/ – stetson Aug 28 '17 at 21:20
  • The object issues is resolved... however strangely the headerData comes back as undefined.... however my data.d has the returnedstring..... This tells me that something is wrong with the way my jsfiddle data is formatted, vs my actual data returned – Philo Aug 28 '17 at 21:37
  • That would make sense. It wouldn't hurt to throw a console log in your code to see what data you're actually getting back. A great ticket would be to do something like this `console.log(JSON.stringify(data[0], null, 2);` This will print the `data[0]` object in your console with formatting. – stetson Aug 28 '17 at 21:40
  • console.log show:- "[{\"Customer Name\":\"xxxx\",\"1999\":76.000,\"2000\":68.000,\"2001\":49.000,\"2002\":41.000,‌​\"2003\":47.000,\"2004\":56.000,\"2005\":33.000,\"2006\":51.000,\"2007\":56.000,\‌​"2008\":52.000,\"2009\":55.000,\"2010\":52.000,\"2011\":57.000,\"2012\":55.000,\"‌​2013\":93.000,\"2014\":92.000,\"2015\":62.000,\"2016\":71.833},{\"Customer Name\":\"yyy\",\"1999\":29.000,\"2000\":27.000,\"2001\":35.000,\"2002\":37.000,\‌​"2003\":32.000,\"2004\":29.000,\"2005\":44.000,\"2006\":49.000,\"2007\":69.000,\...... – Philo Aug 28 '17 at 21:54
  • It's cuts off, but you have at least 2 "customers" there. Now just look through the object structure and make sure you're using it correctly. – stetson Aug 28 '17 at 22:07
  • Just step through your code, either debug it or add a bunch of `console.log` statements and maybe try out [rubber ducky debugging](https://rubberduckdebugging.com). – stetson Aug 28 '17 at 22:16