Convert json number to text

I have some json that has integers in it such as quantity, amount etc… I need to display some of these values, since they are not quoted (" ") in the json they come out as type Int32. To display it I have been using the following code

Dim Amt as Int32
Amt = Order.Value(“amount”)
MsgBox(Amt.ToText)

While this works fine it’s a bit tedious if you have many numbers in the json. Is there a better way to handle the conversion from number to text? If anybody is wondering MsgBox(Order.Value(“amount”).ToText) does not work.

I think I’m missing the problem you’re having as JSONItem can naturally cast to string or text.

So

MsgBox(Order.Value(“amount”)) should just work

If it’s not (for some bizarre reason) try

MsgBox(str(Order.Value("amount")))

or

MsgBox(CType(Order.Value("amount"), Text))

eg.

[code]Dim person As New JSONItem
person.Value(“Name”) = “John Doe”
person.Value(“Age”) = 32
person.Value(“Married”) = True
person.Value(“Spouse”) = “Jane Doe”

'works fine
System.DebugLog(person.Value(“Age”))

'works fine
System.DebugLog(str(person.Value(“Age”)))

'works fine
System.DebugLog(CType(person.Value(“Age”), Text))[/code]

[quote=371576:@JulianS]I think I’m missing the problem you’re having as JSONItem can naturally cast to string or text.

So

MsgBox(Order.Value(“amount”)) should just work

If it’s not (for some bizarre reason) try

MsgBox(str(Order.Value("amount")))

or

MsgBox(CType(Order.Value("amount"), Text))

eg.

[code]Dim person As New JSONItem
person.Value(“Name”) = “John Doe”
person.Value(“Age”) = 32
person.Value(“Married”) = True
person.Value(“Spouse”) = “Jane Doe”

'works fine
System.DebugLog(person.Value(“Age”))

'works fine
System.DebugLog(str(person.Value(“Age”)))

'works fine
System.DebugLog(CType(person.Value(“Age”), Text))[/code][/quote]
He’s not using JSONItem, looks like new framework JSON.

You can try casting as Int32:

MsgBox(Int32(Order.Value(“amount”)).ToText)

I haven’t tested this, but it might work. New framework is nice and succinct isn’t it?

If I had to guess, the end goal is not to display them all in multiple MsgBoxes, and that we’re looking for a usable string/text value for the amount? Both solutions equally succinct, neither need to deal with the Integer value.

Old framework (JSONItem and String):

dim sOrderAmount as String = JSONItem.Lookup("amount", 0).StringValue

[s]New Framework (Xojo.Core.Dictionary and Text):

dim txOrderAmount as Text = DictonaryObject.Lookup("amount", 0)

Guess I don’t use the new framework enough to answer that.

You can’t call ToText on an Auto.

Fix’d

Edit: or is it? I can’t seem to find any way to make it succinct without being less clear. With succinct meaning “brief and clear” I have to disagree that the new framework is succinct.

But there is not implied casting. The auto contains an integer, not a text, so it’ll trigger a type mismatch. Auto is not like Variant.

So it sounds like the new framework is less succinct.

You have to test what “amount” is, because who knows that it’s always going to be an integer, then shove it into the appropriate datatype, then use that datatype .ToText?

[quote=371584:@Tim Parnell]So it sounds like the new framework is less succinct.

You have to test what “amount” is, because who knows that it’s always going to be an integer, then shove it into the appropriate datatype, then use that datatype .ToText?[/quote]
That’s basically it. My succinct comment was very much sarcasm.

There’s a lot of using Introspection with Auto in the new framework. Which also doesn’t seem to ever release the introspection objects, according to the runtime object list.

So the most “correct” way to do it is something like:

Dim Value As Auto = Order.Value("amount") Dim ValueInfo As Xojo.Introspection.TypeInfo = Xojo.Introspection.GetType(Value) Select Case ValueInfo.FullName Case "Text" Dim TextValue As Text = Value MsgBox(TextValue) Case "UInt32" Dim UInt32Value As UInt32 = Value MsgBox(UInt32Value.ToText) Case "Int32" Dim Int32Value As Int32 = Value MsgBox(Int32Value.ToText) End Select

And so on. You could get any of Double, [U]Int(8|16|32|64), or technically just about anything. It’s pretty horrifying. But it’s generally easier to cut corners and write exception handlers in case something doesn’t meet expectations.

Oh and for the record, casting from Auto to Int32 does not work. So even my original proposal won’t work. At this point, it would be easier to write some kind of AutoToInteger function:

Public Function AutoToInteger(Value As Auto) as Integer #Pragma BreakOnExceptions Off Dim IntValue As Integer Try IntValue = Value Catch Err As TypeMismatchException IntValue = 0 End Try Return IntValue End Function

Oh, jeeze, I didn’t catch the sarcasm and then got really confused.

Yeah, I found that out just now (I started in on making a new-framework friendly variant class). It looks like casting Auto doesn’t work for anything.

Yeah, it really is easier just to use Try blocks to attempt getting the object into a potential class. But certain casting does work, for example you can put an Int64 into Auto and then put that Auto into Int32. So the only way to truly do the right thing is with introspection.

So when I try MsgBox(str(Order.Value(“amount”))) I get a compile message
There is more than one item with this name and it’s not clear to which this refers. It highlights “MsgBox(Str”

When I try MsgBox(Int32(Order.Value(“amount”)).ToText) I get a compile message
Type mismatch error, expected Int32 got Auto

So for clarification I am not displaying a bunch of numbers I am displaying a list of product orders which includes quantities, amounts price etc… That all has to be converted to display on screen either as a MsgBox, Label or Listbox. This information is coming ion as a json array of objects. Had the numbers been text this would have been simple.

The best suggestion I have seen is to write an extension… Still have to take multiple steps but it’s hidden and reusable. I’ll report back to confirm how it works.

Ah right, autos.

Try this:

https://forum.xojo.com/conversation/post/355466

Coming from json it says it’s defined as Int32. The example in that link will work too. Its very close to the solution I just implemented. Its an extension so all I need is a single line.

MsgBox(order.ValueAsText("amount"))

Here is the extension code.

[code]
Dim value As Auto = dict.Value(key)

Dim info As Xojo.Introspection.TypeInfo
info = Xojo.Introspection.GetType(value)

Dim textValue As Text

Select Case info

Case GetTypeInfo(Integer)
Dim i As Integer = value
textValue = i.ToText

Case GetTypeInfo(Double)
Dim d As Double = value
textValue = d.ToText

Case GetTypeInfo(Text)
textValue = value

Case GetTypeInfo(Boolean)
Dim b As Boolean = value
If b Then
textValue = “True”
Else
textValue = “False”
End If

End Select

Return textValue[/code]

Paul Lefebvre gets the credit for this elegant solution, thanks Paul.

Those all use String, so isn’t all this work getting a Text value wasted anyway?

Not everything coming from json is text. If the data is not inside quotes then it is treated as a number if in fact it’s a number. I believe it’s json good practice to use quotes on numbers if they are to be treated as text. The extension always delivers back Text regardless of the data type. My code is intricate and having something like separated out keeps it much easier to read and reuseable.

I understand that. I’m just wondering why you want to get the value as Text instead of String. Your Text values are just being auto-converted to String for display anyway. I would think (could be wrong) that String would be easier to get in the first place.

Edit: I see where Tim was going with that now.