Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Usage difference between ion.Decimal and ion.dom.Decimal classes? #739

Open
normand1 opened this issue Feb 1, 2023 · 1 comment
Open

Comments

@normand1
Copy link

normand1 commented Feb 1, 2023

I ran into an issue today trying to write to the QLDB database with a Decimal class I built like this:

const decimalNumber = new ion.Decimal('1.0');

When I tried writing this value to QLDB I received this error message:
"Ion Binary: value.writeTo is not a function"

I ended up wrapping decimalNumber with ion.dom.Decimal like so:

const writableDecimal = new ion.dom.Decimal(decimalNumber);

I was then able to write this Decimal value to QLDB.

These two Decimal classes seem to have some of the same usage and functionality, but I don't think it's made very clear that there are multiple Decimal classes in the documentation from what I can see. I'm also not sure if this the correct way to handle a strict string to decimal conversion for ION values.

It might be helpful to just add a string constructor on the ion.dom.Decimal class so I wouldn't need to make multiple hops here:

const decimalNumber = new ion.Decimal('1.0');
const writableDecimal = new ion.dom.Decimal(decimalNumber);
@zslayton
Copy link
Contributor

zslayton commented Mar 2, 2023

Sorry for the delayed reply. I agree that this should be made clearer.

Decimal and Timestamp are the two Ion scalar types for which no existing JavaScript type can be used as representation. An ion.Decimal is the numeric quantity associated with an Ion literal like 1.0, but is not capable of storing annotations.

The types in the dom module are full Ion values (an unfortunately overloaded term 😞), which is to say that they are an (annotations, value) pair. In the case of dom.Decimal, it's a set of annotations and an ion.Decimal representing the numeric quantity.

The types in dom.Decimal are also wired up to behave like JavaScript types where possible. This means that you can use dom.Decimal in places where a Number (capital N) is allowed/expected, which is not true of ion.Decimal.

Unfortunately, Value.from(jsValue) doesn't have a hinting system (See #620), so if you give it a Number it will treat it as either an Ion integer or float, never a decimal.

In your case, you could do this:

const writableDecimal = ion.load('1.0');

This is friendlier syntax, though it is slower than your example code because it has to create an Ion reader to parse the provided text.

I think we can/should modify dom.Decimal's constructor to allow a numeric or string representation so you can do this:

// From integer Number
const writableDecimal = new dom.Decimal(1.0);
// From non-integer Number
const writableDecimal = new dom.Decimal(1.5);
// From string
const writableDecimal = new dom.Decimal('1.0');

I've opened #745 to track this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants