javascriptscalabigdecimalscala.js

How do I use a BigDecimal from Scala.js in my JavaScript application?


I have this Scala object:

@JSExportTopLevel("Calculator")
object Calculator {

  @JSExport
  def calculate(): BigDecimal = 3.14
}

I can call the exported singleton method from my JavaScript application as expected, but the result is difficult to work with:

let result = Calculator.calculate()
assert(result == 123); // passes
assert(result === 123); // fails
assert(result + 1 == 124); // fails, is actually "1241"

This is what result looks like in the browser console:

Object { s_math_BigDecimal__f_bigDecimal: {…}, s_math_BigDecimal__f_mc: {…}, s_math_BigDecimal__f_computedHashCode: 1565550863 }
    s_math_BigDecimal__f_bigDecimal: Object { Ljava_math_BigDecimal__f__hashCode: 0, "Ljava_math_BigDecimal__f_java$math$BigDecimal$$_bitLength": 9, "Ljava_math_BigDecimal__f_java$math$BigDecimal$$_scale": 2, … }
    s_math_BigDecimal__f_computedHashCode: 1565550863
    s_math_BigDecimal__f_mc: Object { Ljava_math_MathContext__f_precision: 34, Ljava_math_MathContext__f_roundingMode: {…} }
    <prototype>: Object { constructor: $c_s_math_BigDecimal(bigDecimal, mc), hashCode__I: hashCode__I(), equals__O__Z: equals__O__Z(that), … }
        "$classData": Object { constr: undefined, arrayDepth: 0, arrayEncodedName: "Lscala.math.BigDecimal;", … }
        "$div__s_math_BigDecimal__s_math_BigDecimal": function $div__s_math_BigDecimal__s_math_BigDecimal(that)
        "$minus__s_math_BigDecimal__s_math_BigDecimal": function $minus__s_math_BigDecimal__s_math_BigDecimal(that)
        "$plus__s_math_BigDecimal__s_math_BigDecimal": function $plus__s_math_BigDecimal__s_math_BigDecimal(that)
        "$times__s_math_BigDecimal__s_math_BigDecimal": function $times__s_math_BigDecimal__s_math_BigDecimal(that)
        byteValue__B: function byteValue__B()
        compare__O__I: function compare__O__I(that)
        constructor: function $c_s_math_BigDecimal(bigDecimal, mc)
        doubleValue__D: function doubleValue__D()
        equals__O__Z: function equals__O__Z(that)
        equals__s_math_BigDecimal__Z: function equals__s_math_BigDecimal__Z(that)
        floatValue__F: function floatValue__F()
        hashCode__I: function hashCode__I()
        intValue__I: function intValue__I()
        isDecimalDouble__Z: function isDecimalDouble__Z()
        isValidByte__Z: function isValidByte__Z()
        isValidChar__Z: function isValidChar__Z()
        isValidInt__Z: function isValidInt__Z()
        isValidLong__Z: function isValidLong__Z()
        isValidShort__Z: function isValidShort__Z()
        isWhole__Z: function isWhole__Z()
        longValue__J: function longValue__J()
        remainder__s_math_BigDecimal__s_math_BigDecimal: function remainder__s_math_BigDecimal__s_math_BigDecimal(that)
        shortValue__S: function shortValue__S()
        toBigIntExact__s_Option: function toBigIntExact__s_Option()
        toBigInt__s_math_BigInt: function toBigInt__s_math_BigInt()
        toString__T: function toString__T()
        <prototype>: Object { constructor: $c_s_math_ScalaNumber() }

How is one meant to use this thing? Should I export a different type? Or something else?


Solution

  • You won't be able to directly manipulate a BigDecimal from JavaScript code, as it exports nothing.

    Do you actually need big decimal semantics? If not, perhaps you meant to return a Double instead, which is a JavaScript number. If yes, then you'll have to provide another exported object with exported methods to specifically manipulate instances of BigDecimal.