6

I am trying to get JSON from the url, But in the response object duplicate keys are removed. Is there any way to fetch it completely without removing the duplicate keys? Here is my js Code

$('document').ready(function(){
    var s = $.getJSON("new.json");
    console.log(s);
});

following is my new.json

{
"s": "wae",
"s": "asd"
}

But in console i am getting the json Object as follows

responseJSON: Object
s: "asd"

Thanks in advance

Callum Linington
  • 14,213
  • 12
  • 75
  • 154
Saju
  • 61
  • 1
  • 1
  • 4
  • 4
    The only way would be to parse the JSON manually (as in, fetch the JSON as normal text) – Prisoner Jun 15 '15 at 10:22
  • Indeed. You'll have to write a custom JSON parser from scratch (unless someone else has published one, but I'm not away of any examples and library recommendations are off-topic here anyway). That's probably too broad a subject for Stackoverflow. – Quentin Jun 15 '15 at 10:32

5 Answers5

3

If you can't change the server response, for simple JSON data you can request the json like text and parse it like a string:

var check = new RegExp('["\']([^\'"]*)[\'"][^:]*:[^"\']*["\']([^\'"]*)[\'"]',"g");
    $.ajax({
        url : "text.json",
        dataType : "text",
        success : function(data){
            var newData = {};
            data.replace(check,function(a,b,c){
                if(typeof newData[b] == "undefined"){
                    newData[b] = c;
                }else if(typeof newData[b] == "object"){
                    newData[b].push(c);
                }else{
                    var ca = newData[b];
                    newData[b] = [ca,c];                     
                }
                return a;
            });
            console.log(newData);
            console.log($.parseJSON(data));
        },
        error : function(e,a){
            console.log(e,a);
        }
    });

in this code newData with your json is:

{"s": ["wae","asd"]}
Frogmouth
  • 1,808
  • 1
  • 14
  • 22
1

Keys in a JSON object should be unique. Otherwise the last key with the value is usually the one presented when requesting that key. Having keys the same also makes it more difficult to differentiate between attributes of an object. The whole point of a key is to make it accessible and available.

To get around this you could always:

  1. Change the keys in your JSON

  2. Change the JSON to contain an array

    {"s": ["wae","asd"]}

The JavaScript Object Notation (JSON) Data Interchange Format) (RFC7159) says:

The names within an object SHOULD be unique.

In this context should must be understood as specified in RFC 2119

SHOULD This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course.


RFC 7159 explains why unique keys are good: > An object whose names are all unique is interoperable in the sense > that all software implementations receiving that object will agree on > the name-value mappings. When the names within an object are not > unique, the behavior of software that receives such an object is > unpredictable. Many implementations report the last name/value pair > only. Other implementations report an error or fail to parse the > object, and some implementations report all of the name/value pairs, > including duplicates. > > JSON parsing libraries have been observed to differ as to whether > or not they make the ordering of object members visible to calling > software. Implementations whose behavior does not depend on member > ordering will be interoperable in the sense that they will not be > affected by these differences.
Community
  • 1
  • 1
Craicerjack
  • 6,203
  • 2
  • 31
  • 39
  • 11
    While this is all good advice, it doesn't actually answer the question. – Quentin Jun 15 '15 at 10:31
  • @Quentin yes but it does look like he is able to change the JSON himself, from the example anyway, and instead of trying to answer the question, I felt it would be no harm to try to give an idea of good practices that would enable a workaround. The above answer is also quite big for a comment and would suffer from a lack of formatting. – Craicerjack Jun 15 '15 at 10:40
  • i just given a sample. actually i am not able to change the JSON. What i want to know whether is it possible to fetch without duplicates. From the comments i guess its not possible. – Saju Jun 15 '15 at 10:57
  • 1
    @Quentin ,@Craicerjack ThankYou – Saju Jun 15 '15 at 10:59
1

This is not possible with JSON.parse(). I believe that the more modern ES spec states that subsequent keys override earlier ones.

However, the JSON spec does not disallow JSON like this. And there are alternative parsers and serializers which can produce and consume such JSON from within JavaScript. For example, you can use the SAX-style JSON parser clarinet:

const clarinet = require('clarinet');

const parser = clarinet.parser();
const result = [];
parser.onkey = parser.onopenobject = k => {
    result.push({key: k, value: null});
};
parser.onvalue = v => {
    result[result.length - 1].value = v;
};
parser.write('{"a": "1", "a": "2"}').close();

console.log(result);
// [ { key: 'a', value: '1' }, { key: 'a', value: '2' } ]

If you are wondering about how to use require() from the browser, learn how to use webpack.

Panda
  • 6,955
  • 6
  • 40
  • 55
binki
  • 7,754
  • 5
  • 64
  • 110
1

JSON allows duplicates keys but Javascript Objects do not.

Because keys can be duplicated, that means the JSON cannot be represented as key/value based dictionary and cannot be converted directly to a Javascript Object.

You will have to "walk" through each key/value pair in the JSON and then process it as you see fit. I don't know what structure you are looking to convert into, but it as long as it's not a Javascript Object, then it's fine. For example, you might walk through a JSON object and output the values to an .ini or .css file where "keys" can be repeated.

JSON.parse() will not work because that will try to parse into a Javascript Object, which does not allow duplicated keys. The solution there is to simply overwrite any previous value if the key is reused. But, we can use code based on how JSON.parse() works and instead of setting properties on a Javascript Object, you can split from there and apply your custom solution.

You can modify a complete JSON parser like json2 or use parsers that stream keys as they arrive like clarinet or Oboe.js.

ShortFuse
  • 5,970
  • 3
  • 36
  • 36
0

You may try using given structure to use same key multiple times:

[
  {"s": "wae"},
  {"s": "asd"}
]

As suggested by Craicerjack, you can also go for array for multiple values with single key:

{"s": ["wae","asd"]}