MyDaftQuestions MyDaftQuestions - 6 months ago 6
JSON Question

Are Json values type specific

I'm trying to understand what is going on when I query data from a database and provide it to JSON and then push it to a GUI, in regards to what and when is converting to a string.

If I make a call to a database and provide this data as JSON to the front end, my JSON may look like

MyData{ [["Name": "Anna", "Age": 50],["Name": "Bob", "Age": 40 ]};


Visually it appears as if the value for
Name
is a string (as it's in quote marks) and the value for
Age
is an integer (as of no quote marks).

My 2 questions are


  1. Is my understanding that the value for
    Name
    is a string and the value of
    Age
    is an integer or does JavaScript convert/cast behind the scenes?

  2. How would I specify the type
    DateTime
    . According to The "right" JSON date format I actually just ensure the format is correct but ultimately it's a string.


Answer

Is my understanding that the value for Name is a string and the value of Age is an integer...?

Almost. It's a number, which may or may not be an integer. For instance, 10.5 is a number, but not an integer.

...or does JavaScript convert/cast behind the scenes?

JavaScript and JSON are different things. JSON defines that the number will be represented by a specific format of digits, . and possibly the e or E character. Whatever environment you're parsing the JSON in will map that number to an appropriate data type in its environment. In JavaScript's case, it's an IEEE-754 double-precision binary floating point number. So in that sense, JavaScript may cast/convert the number, if the JSON defines a number that can't be accurately represented in IEEE-754, such as 9007199254740999 (which becomes the number 9007199254741000 because IEEE-754 only has ~15 digits of decimal precision).

How would I specify the type DateTime. According to The "right" JSON date format I actually just ensure the format is correct but ultimately it's a string.

JSON has a fixed number of types: object, array, string, number, boolean, null. You can't add your own. So what you do is encode any type meta-data you want into either the key or value, or use an object with separate properties for type and value, and enforce that agreement at both ends.

An example of doing this is the common format for encoding date/time values: "/Date(1465198261547)/". As far as the JSON parser is concerned, that's just a string, but many projects use it as an indicator that it's actually a date, with the number in the parens being the number of milliseconds since The Epoch (Jan 1 1970 at midnight, GMT).

Two concepts related to this are a replacer and a reviver: When converting a native structure to JSON, the JSON serializer you're using may support a replacer which lets you replace a value during the serialization with another value. The JSON parser you're using may support a reviver that lets you handle the process in the other direction.

For example, if you were writing JavaScript code and wanted to preserve Dates across a JSON layer, you might do this when serializing to JSON:

var obj = {
    foo: "bar",
    answer: 42,
    date: new Date()
};
var json = JSON.stringify(obj, function(key, value) {
    var rawValue = this[key];
    if (rawValue instanceof Date) {
        // It's a date, convert it to our special format
        return "/Date(" + rawValue.getTime() + ")/";
    }
    return value;
});
console.log(json);

That uses the "replacer" parameter of JSON.stringify to encode dates in the way I described earlier.

Then you might do this when parsing that JSON:

var json = '{"foo":"bar","answer":42,"date":"/Date(1465199095286)/"}';
var rexIsDate = /^\/Date\((-?\d+)\)\/$/;
var obj = JSON.parse(json, function(key, value) {
    var match;
    if (typeof value == "string" && (match = rexIsDate.exec(value)) != null) {
        // It's a date, create a Date instance using the number
        return new Date(+match[1]);
    }
    return value;
});
console.log(obj);

That uses a "reviver" to detect keys in the special format and convert them back into Date instances.