JSON Left Out Infinity and Nan; JSON Status in Ecmascript

Serialization of NaN and Infinity in JSON. Why not supported?

Per RFC 7159 - The JavaScript Object Notation (JSON) Data Interchange Format

Numeric values that cannot be represented in the grammar below (such as Infinity and NaN) are not permitted.

I would speculate that this is because NaN and Infinity don't actually represent numbers and/or can't be represented by any type of numeric format.

Force JSON.stringify() to emit NaN / Infinity or JS JSON lib that does so

Here is an example

Javascript

var array1 = [-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity],
json = JSON.stringify(array1, function (key, value) {
if (value !== value) {
return 'NaN';
}

if (value === Infinity) {
return 'Infinity';
}

if (value === -Infinity) {
return '-Infinity';
}

return value;
}),
array2 = JSON.parse(json, function (key, value) {
if (value === 'NaN') {
return NaN;
}

if (value === 'Infinity') {
return Infinity;
}

if (value === '-Infinity') {
return -Infinity;
}

return value;
});

console.log(json);
console.log(array2);

Output

["-Infinity",-1,0,1,2,"NaN",4,5,"Infinity"]
[-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity]

References

JSON.stringify

JSON.parse

On jsFiddle

Update:

Javascript

var array1 = [-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity],
json = JSON.stringify(array1, function (key, value) {
if (value !== value) {
return '0/0';
}

if (value === 1/0) {
return '1/0';
}

if (value === -1/0) {
return '-1/0';
}

return value;
}),
array2 = JSON.parse(json, function (key, value) {
if (value === '0/0') {
return 0/0;
}

if (value === '1/0') {
return Infinity;
}

if (value === '-1/0') {
return -1/0;
}

return value;
});

console.log(json);
console.log(array2);

Output

["-1/0",-1,0,1,2,"0/0",4,5,"1/0"]
[-Infinity, -1, 0, 1, 2, NaN, 4, 5, Infinity]

On jsFiddle

JSON.stringify converting Infinity to null

Like the other answers stated, Infinity is not part of the values JSON can store as value.

You can reverse the censor method on parsing the JSON:

var c = JSON.parse(b, function (key, value) {
return value === "Infinity" ? Infinity : value;
});

In Angular 2, how do you intercept and parse Infinity / NaN bare-words in JSON responses?

I was able to figure out how to achieve this, and it came down to:

  1. Modifying the request to return as text instead of json
  2. Catch the text response and replace the bare word symbols with specific string flags
  3. Parse the text into an object using JSON.parse, providing a reviver function to replace the specific string flags with the javascript version of +/-Infinity and NaN

Here's the Angular HttpInterceptor I came up with:

import {Injectable} from '@angular/core';
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';

import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';

@Injectable()
export class JsonBareWordNumericSymbolTranslator implements HttpInterceptor {
private static infinityFlag = '__INFINITY_FLAG__';
private static negInfinityFlag = '__NEG_INFINITY_FLAG__';
private static nanFlag = '__NAN_FLAG__';

private static replaceBareWordSymbolsWithFlags(body: string): string {
const infinityBareWordPattern = /(": )Infinity(,?)/;
const negInfinityBareWordPattern = /(": )-Infinity(,?)/;
const nanBareWordPattern = /(": )NaN(,?)/;
return body
.replace(infinityBareWordPattern, `$1"${this.infinityFlag}"$2`)
.replace(negInfinityBareWordPattern, `$1"${this.negInfinityFlag}"$2`)
.replace(nanBareWordPattern, `$1"${this.nanFlag}"$2`);
}

private static translateJsonWithFlags(substitutedBody: string): any {
return JSON.parse(substitutedBody, (key: string, value: string) => {
if (value === this.infinityFlag) {
return Infinity;
} else if (value === this.negInfinityFlag) {
return -Infinity;
} else if (value === this.nanFlag) {
return NaN;
} else {
return value;
}
});
}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.responseType !== 'json') {
// Do not modify requests with response types other than json
return next.handle(req);
}

return next.handle(req.clone({responseType: 'text'})).pipe(
map((event) => {
if (!(event instanceof HttpResponse)) {
return event;
}

const substitutedBody = JsonBareWordNumericSymbolTranslator.replaceBareWordSymbolsWithFlags(event.body);
const parsedJson = JsonBareWordNumericSymbolTranslator.translateJsonWithFlags(substitutedBody);
return event.clone({body: parsedJson});
})
);
}
}

Are null and Infinity interchangeable in Javascript?

Here's the same code in a snippet you can run in your browser. As you can see, Infinity and null are not equal.

let RANGE_DEFAULT_OPTIONS = { min: 0, max: Infinity };
console.log(RANGE_DEFAULT_OPTIONS);
console.log('strict equality', Infinity === null);
console.log('loose equality', Infinity == null);


Related Topics



Leave a reply



Submit