Open ajsergeev opened 5 years ago
This is a known, and old, bug in dart2js (#11551). Closing this issue as a duplicate of that bug.
The identity on doubles is defined as comparing the bit-representation as IEEE-754 64-bit floating points, which would make a NaN identical to itself (but not necessarily to another NaN).
Dart2js uses JavaScript ===
for identity, which differs from the required behavior on NaN
(not identical to itself) and identical(0.0, -0.0)
which wrongly returns true.
I'm not about identical. Your JSON Encoder customization doesn't work and I don't see a good way to fix it. Yes, it's because of identical, but if it's impossible to fix identical, you must provide a way to customize identical for encoder or don't use identical at all there, otherwise toEncodable parameter is useless and doesn't work!
I understand I can preprocess Map and fix all NaNs before call to Encoder (this is my temp workaround for this), but it's not good way to solve this and if dart pretend to good architecture it must be solved a better way.
I see. So even if the problem really is identical
, we should make sure that our jsonEncoder
doesn't actually depend on identical
in that case.
yes, that might solve this, thanks!
I'm not sure if it is related, but we ran into a very similar problem. The following code works with dart2js (and DartPad), but fails when run via dartdevc:
print(json.encode(double.nan, toEncodable: (_) => 'NaN'));
print(json.encode([double.nan], toEncodable: (_) => 'NaN'));
print(json.encode({'foo': [double.nan]}, toEncodable: (_) => null));
Code is also here: https://dartpad.dartlang.org/0bf3d37cc6773abf233843556af973a4
So for me it looks like dart2js actually does work, but dartdevc fails?
We are using customized JSON Encoder to serialize NaN. Now we moving to dart2 from dart1 and I faced this issue: 1) encoder = new JsonEncoder(_encoder); 2) static dynamic _encoder(value) { if (value is num) { num n = value; if (n.isNaN) { return 'NaN'; } } } 3) _encoder method works ok 3) Finally, writeObject() calls _removeSeen() method, which relies on identical. As both parameters are NaNs for identical, it fails and overall process fails, see screenshots attached.