Help With JSON formatting

Post your Gambas programming questions here.
AndyGable
Posts: 359
Joined: Wednesday 2nd December 2020 12:11am
Location: Northampton, England
Contact:

Re: Help With JSON formatting

Post by AndyGable »

hi Grayghost4

Thank you for your example It worked

Thank-you

Now i just need to get status again :)
AndyGable
Posts: 359
Joined: Wednesday 2nd December 2020 12:11am
Location: Northampton, England
Contact:

Re: Help With JSON formatting

Post by AndyGable »

hi Everyone

so I have this working now (the JSON is being sent to the server with no errors) but when I get the data back from the Server it is in the following format

Code: Select all

{"location":"https://test.connect.paymentsense.cloud/pac/terminals/12345678/transactions/661c943f","notifications":["TRANSACTION_STARTED"]}
Ivbe tried to use this

Code: Select all

If http.Status < 0 Then 
        Global.addtoStatusList("SORRY A Error was detected")
        global.AddToDebugList(http.ErrorText)
    Else
        ' Success - read data
        If Lof(http) Then Read #http, global.sBuffer, Lof(http)
                Global.addtoStatusList(global.sBuffer)


            Dim vNew As Variant = JSON.Decode(global.sBuffer)
            
                global.AddToDebugList(global.sBuffer)
               
                Message(vNew["notifications"])
End if
but I get a error on Message(vNew["notifications"]) saying "Type Mismatch: wanted string got Variant[] instead"

do i have to process the output differently when it has more then one feed? Im trying to get the TRANSACTION_STARTED bit
User avatar
grayghost4
Posts: 174
Joined: Wednesday 5th December 2018 5:00am
Location: Marengo, Illinois usa

Re: Help With JSON formatting

Post by grayghost4 »

Message requires a string and vNew is a variant ... try this :


Message(Str(vNew["notifications"]))
AndyGable
Posts: 359
Joined: Wednesday 2nd December 2020 12:11am
Location: Northampton, England
Contact:

Re: Help With JSON formatting

Post by AndyGable »

That now show but I can not seem to get the second set of data in the JSON feed

I need to read from the notifications Section

I have the following

Code: Select all

{"location":"https://test.connect.paymentsense.cloud/pac/terminals/12345678/transactions/661c943f","notifications":["TRANSACTION_STARTED"]}
How do I get the "TRANSACTION_STARTED" from the notifications area?
User avatar
BruceSteers
Posts: 1523
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Help With JSON formatting

Post by BruceSteers »

The format is a JSON string so use Decode to process it as a collection.
the notifications is an array so use [0] to get the first item.
' this is your string...

Dim s As String = "{\"location\":\"https://test.connect.paymentsense.cloud/pac/terminals/12345678/transactions/661c943f\",\"notifications\":[\"TRANSACTION_STARTED\"]}"

 ' turn the JSON string into a collection
Dim jc As Collection = JSON.Decode(s) 

' print the data..
Print jc["location"]
Print jc["notifications"][0]

Last edited by BruceSteers on Wednesday 17th August 2022 4:35pm, edited 1 time in total.
If at first you don't succeed , try doing something differently.
BruceS
AndyGable
Posts: 359
Joined: Wednesday 2nd December 2020 12:11am
Location: Northampton, England
Contact:

Re: Help With JSON formatting

Post by AndyGable »

BruceSteers wrote: Wednesday 17th August 2022 3:56pm The format is a JSON string so use Decode to process it as a collection.
the notifications is an array so use [0] to get the first item.
' this is your string...

Dim s As String = "{\"location\":\"https://test.connect.paymentsense.cloud ... ifications\":[\"TRANSACTION_STARTED\"]}"

 ' turn the JSON string into a collection
Dim jc As Collection = JSON.Decode(s) 

' print the data..
Print jc["location"]
Print jc["notifications"][0]

THANK-YOU THANK-YOU THANK-YOU :)
User avatar
BruceSteers
Posts: 1523
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Help With JSON formatting

Post by BruceSteers »

AndyGable wrote: Wednesday 17th August 2022 4:19pm
BruceSteers wrote: Wednesday 17th August 2022 3:56pm The format is a JSON string so use Decode to process it as a collection.
the notifications is an array so use [0] to get the first item.
THANK-YOU THANK-YOU THANK-YOU :)
You're welcome.
It would probably be good to make a class to handle your messages and fire events relevant to the message type.

attached is a simple example I just made of a class that you can send your device text to and it will fire events based on the message type. I called it DeviceMessage.class
It just handles 'notifications' or it reports an unhandled message for anything else...
' Gambas class file

'' Get the notifications sent
Static Property Read Notifications As String[] Use $aNotifications
'' get the location
Static Property Read Location As String Use $sLocation

'' fires when a message contains notifications.
Event Notify

'' process text from the device
Public Sub _call(Text As String)

  Dim jc As Collection = JSON.Decode(Text)

  $sLocation = jc["location"]
  jc.Remove("location")

  For Each jc

    If jc.Key = "notifications" ' message is notifications so set property, raise event and remove from message list
      $aNotifications = jc["notifications"]
      Raise Notify
      jc.Remove("notifications")
      Continue
    Endif

    ' If here there is an unhandled message
    Print "\e[31mUnhandled message!!\e[0m " & jc.Key;;

    If TypeOf(jc[jc.Key]) = gb.String Then
      Print "'string'";; jc[jc.Key]
    Else If TypeOf(jc[jc.Key]) = gb.Integer Then
      Print "'integer'";; Str(jc[jc.Key])

    Else If TypeOf(jc[jc.Key]) = gb.Object Then ' any array is an Object type
      If Object.Type(jc[jc.Key]) Ends "[]" Then
        Print "'array'";; Object.Type(jc[jc.Key])
      Else
        Print "'object'";; Object.Type(jc[jc.Key])
      Endif

    Else
      Print "Unhandled type"
    Endif
  Next

End
Now in your application you would create the instance of the DeviceMessage class like so...
  hMessager = New DeviceMessage As "DeviceMessage"
then send the global.sBuffer strings like
           Global.addtoStatusList(global.sBuffer)
           hMessager(global.sBuffer)
           global.AddToDebugList(global.sBuffer)
a notifications message will fire the Notify event
'' a notifications message sent to the buffer triggers this event filling in the Location and Notifications property
Public Sub DeviceMessage_Notify()

End
possibly not what you want but I was bored and thought this might help you with understanding collections, how to process various unknown variant types and setting up events.
Perhaps you could expand it do suit your needs.

Happy coding :)
BruceS
Attachments
ProcessMesagges-0.0.tar.gz
(12.48 KiB) Downloaded 79 times
If at first you don't succeed , try doing something differently.
BruceS
AndyGable
Posts: 359
Joined: Wednesday 2nd December 2020 12:11am
Location: Northampton, England
Contact:

Re: Help With JSON formatting

Post by AndyGable »

Would that class help send status messages to my point of sale software?
User avatar
BruceSteers
Posts: 1523
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Help With JSON formatting

Post by BruceSteers »

AndyGable wrote: Wednesday 17th August 2022 7:53pm Would that class help send status messages to my point of sale software?
It's a bare bones example.
I don't know your device , you would have to add what you want to it and make it work how you need it to.

If there is a status specific message string then process it like the notifications message.

The above post has a test source app attached showing how to use it.

It will print messages about anything sent that is not notifications showing the datatype of the message so you can figure it out from there I should think 😊
If at first you don't succeed , try doing something differently.
BruceS
User avatar
BruceSteers
Posts: 1523
Joined: Thursday 23rd July 2020 5:20pm
Location: Isle of Wight
Contact:

Re: Help With JSON formatting

Post by BruceSteers »

Pretty sure you could reverse the process, so make a collection then use JSON.Encode() to create a message string to send to the device. (Only a guess though, you'd have to experiment)

You could then add a DeviceMessage.Send() command to the class easily enough.
If at first you don't succeed , try doing something differently.
BruceS
Post Reply