proofgeist / fm-json-additions

MIT License
27 stars 12 forks source link

JSON.Merge transforms UUIDnumbers to scientific notation #24

Open marcoaperez opened 4 years ago

marcoaperez commented 4 years ago

I have found an issue with the JSON.Merge, it transforms the uuids numeric to scientific notation. It is an issue I found using the Defaults in the Generator

Let ( [ ~var1 = JSONSetElement ( "" ; "EstadoNum" ; 0 ; JSONNumber ) ; ~var1 = JSONSetElement ( ~var1 ; "FechaEnvio" ; Get (CurrentDate ) ; JSONString ) ] ; JSONFormatElements ( JSON.Merge ( ~var1 ; DBTransactions::ScriptParameter ) ) & ¶ & ¶ & JSONFormatElements ( DBTransactions::ScriptParameter ) )

Result, first the merge and second the original json { "Cantidad" : 0, "ContadorCobro" : "", "ContadorPago" : "", "EstadoNum" : 0, "FechaEnvio" : "19/6/2020", "TipoEfectoNum" : 0, "kplnEfecto" : "", "_kflnActores" : "", "_kfln__Cliente" : 17477, "_kflnDatos" : 2.29396990907313e+57, "_kflnProyecto" : 4.86303750114176e+57, "_kfln__Rol" : 5.92391984993548e+57, "_kflnSede" : 1.71582407996166e+38, "_kfltUsuario" : "639B9083-D1FF-40A4-B2D6-DA7E791F82EC" } { "Cantidad" : 0, "ContadorCobro" : "", "ContadorPago" : "", "EstadoNum" : 0, "TipoEfectoNum" : 0, "kplnEfecto" : "", "_kfln__Actores" : "", "_kflnCliente" : "17477", "_kflnDatos" : "2293969909073132126349337718155948834381243777899890985218", "_kfln__Proyecto" : "4863037501141760381596553479032162072666417933849276737514", "_kflnRol" : "5923919849935484360368756433328194485542484165209662045958", "_kfln__Sede" : "171582407996166204649576529716288828130", "_kflt__Usuario" : "639B9083-D1FF-40A4-B2D6-DA7E791F82EC" }

marcoaperez commented 4 years ago

This is the test that I run with JSONMerge simple

Test::JSON { "firstName" : "todd", "lastName" : "geist" }

Test::Expression JSON.Merge( Test::JSON ; "{\"a\" : 2293969909073132126349337718155948834381243777899890985218 , \"b\" : \"4863037501141760381596553479032162072666417933849276737514\" }" )

Actual Result { "a" : 2.29396990907313e+57, "b" : 4.86303750114176e+57, "firstName" : "todd", "lastName" : "geist" }

Expected Result { "a" : 2.29396990907313e+57, "b" : "4863037501141760381596553479032162072666417933849276737514", "firstName" : "todd", "lastName" : "geist" }

joshormond commented 4 years ago

This is a limit of floating point math, not specifically with FileMaker. Depending on the precision used, the number of characters varies. In FileMaker's case, they use Double Extended precision, which results in about 18 characters of precision. After that, numbers are returned as scientific notation.

The solution right now is to handle your UUIDNumbers as Strings instead of numbers. There is no real harm with this, just have to remember to force it back to a number if you need to do any math or number based comparison.

marcoaperez commented 3 years ago

I use it as JSONString, but the JSONMerge won't work as String

mbcbus commented 1 year ago

This is a limit of floating point math, not specifically with FileMaker. Depending on the precision used, the number of characters varies. In FileMaker's case, they use Double Extended precision, which results in about 18 characters of precision. After that, numbers are returned as scientific notation.

The solution right now is to handle your UUIDNumbers as Strings instead of numbers. There is no real harm with this, just have to remember to force it back to a number if you need to do any math or number based comparison.

To clarify @joshormond - The custom function takes the UUID Number that IS already typecast as a string, and changes it BACK to a number. automatically changing castings is kind of dangerous and can bite you if you're expecting that UUIDNumber to be a string field.

I came here to report this issue in relation to this custom function being in FMBetterForms' helper file and having this same issue.

I'm surprised this hasn't been updated in over 2 years.

joshormond commented 1 year ago

To clarify @joshormond - The custom function takes the UUID Number that IS already typecast as a string, and changes it BACK to a number. automatically changing castings is kind of dangerous and can bite you if you're expecting that UUIDNumber to be a string field.

I agree this is the progression causing the issue. My assumption is 1 of 2 things, either Geist was working with this in a way that it didn't matter, or they haven't looked at this in a long time. I also assume they may be just using Javascript to handle this type of stuff.

So either the JSON is simple enough they haven't run into it, or the complex JSON they just use Javascript to transform.

salgoya commented 1 year ago

Hi all

that custom function was created before JSONGetElementType was introduced in FileMaker. The fix is changing the line

JSONType = If( needToCheckForNumber and GetAsText(thisValue) <> GetAsNumber(thisValue) ; JSONString ; "") ; to
JSONType = JSONGetElementType ( source; thisKey );

after the change, the two lines before it can also be deleted.