REST fromJSON nested structure date not working, getting "Datatype value is not a number" for a date, not possible to debug in Atelier.

Atelier, Ensemble

Hi,

I am having a problem in REST service when de-serializing JSON using a nested Property.

I am new to Intersystems and my first time creating REST Service. I setup Atelier dev environment. The worst IDE I have ever worked in. I was able to  attach to a process in the debug perspective and step through the code, but one cannot see contents of variables nor print anything to the console, so it is useless as a debugging tool. When looking at a variable all it displays is its type of the variable and if I try to "watch" I get:

An internal error occurred during: "Label Job".
java.lang.NullPointerException

SO I am unable to solve the issue I am having with the JSON in my REST service due to being unable to debug properly, so I will appreciate any help on this. I try to explain the issue:

I have a Persistent class Consumer which uses 2 SerialObjects as Properties "ActivePeriod" and "AM", I created a REST service to add records to the Consumer, I use Postman to send JSON for a new Consumer.  I get an error back in Postman as follows:

2019-02-01{"Status":"ERROR #7207: Datatype value '2019-02-01' is not a valid number\r\n  > ERROR #5802: Datatype validation failed on property 'Metadata.ActivePeriod:StartDate', with value equal to \"2019-02-01\""}{
    "errors":[ {
            "code":7207,
            "domain":"%ObjectErrors",
            "error":"ERROR #7207: Datatype value '2019-02-01' is not a valid number\r\n  > ERROR #5802: Datatype validation failed on property 'Metadata.ActivePeriod:StartDate', with value equal to \"2019-02-01\"",
            "errors":[ {
                    "code":5802,
                    "domain":"%ObjectErrors",
                    "error":"ERROR #5802: Datatype validation failed on property 'Metadata.ActivePeriod:StartDate', with value equal to \"2019-02-01\"",
                    "id":"DatatypeValidationFailed",
                    "params":["Metadata.ActivePeriod:StartDate","2019-02-01"
                    ]
                }
            ],
            "id":"DTNotNum",
            "params":["2019-02-01"
            ]
        }
    ],
    "summary":"ERROR #7207: Datatype value '2019-02-01' is not a valid number\r\n  > ERROR #5802: Datatype validation failed on property 'Metadata.ActivePeriod:StartDate', with value equal to \"2019-02-01\""
}

The error is on the Consumer's Property "ActivePeriod" (a SerialObject) Property "StartDate". 

I convert the JSON from Postman to DynamicObject and assign it to a new Consumer record, because the ActivePeriod is a Proeprty and StartDate again a property of that, I assign it as follows:

Set consumerRecord.ActivePeriod.StartDate = obj.activePeriod.startDate

The format of the JSON date is "2019-02-01". It seems to be happy with the date of the Proeprty "dateOfBirth" and "DeceasedDateTime", but they are not nested Properties.

There is no clear documention for InterSystems Caché how the Dynamic Object handles nested Properties and how to retrieve it, I cannot see anything wrong in my code.

 

 

 
Here is the full code listing and following that the JSON I sent in Postman:

 

Postman JSON:

---------------------

{        
        "familyName":  "Smith",
        "firstNames" : "Peter",
        "dateOfBirth": "1978-10-10",
        "isDateOfBirthApproximate": 0,
        "isDeceased":  false,
        "deceasedDateTime": "",
        "activePeriod": {
            "startDate": "2019-02-01",
            "endDate":   "",
            "isActive":  1,
            "reasonChangedOrDeleted":  ""
        },
        "am": {
            "createdBy": "Elize",
            "createdDateTime": "2019-02-22 03:34:00",
            "modifiedBy": "Elize",
            "modifiedDateTime": "2019-02-22 03:34:00"
        }

}

 

  • 0
  • 0
  • 151
  • 4
  • 1

Answers

You get this error (Datatype value '2019-02-01' is not a valid number) because %Date stores data in horolog format, so you need to do one of:

  • (Recommended approach) Convert date value from external format (2019-02-01) into internal format (horolog) using $zdh function:
Set consumerRecord.ActivePeriod.StartDate = $zdh(obj.activePeriod.startDate, 3)
  • Use datatype for which this value is valid, i.e. %TimeStamp. To check, all datatype classes offer IsValid method, you can use it to check value validity
zw ##class(%TimeStamp).IsValid("2019-02-01")
  • If you're using InterSystems IRIS you can store dates as %PosixTime.

 

Regarding Atelier, I use it to debug REST services and it shows variable values. You can try to reinstall it. If you're on Windows you can also use Studio.

Thank you for posting Eduard, you are absolutely right, I scratched around and was just about to post here the solution I found, but it is the same as you are suggesting, so I sovled it by covnerting the date sting to Caché date format with:

Set consumerRecord.ActivePeriod.StartDate = $ZDATEH(obj.activePeriod.startDate, 15)

But the IsValid check I did not know about and will be very handy, because yes, if the date is empty string or not valid the above conversion threw an error as well and I do not want an error since the date may be empty, so I have to test it first, so will add that now. And yes, we are using IRIS, so the %PosicTime tip is handy too.

Comments

Apologies, I forgot to add the REST service code, the POST "AddConsumer" uses "CopyToConsumerFromJSON" and this is the one where the de-serialized dynamic object is assigned to the Consumer record:

 
Spoiler

Elize - I'm sorry to hear that your Atelier experience has been frustrating. I've been able to use the Atelier debugger to step through code and see variable values without any problems, and it sounds like Eduard has as well.

InterSystems provides some resources that may be helpful to you:

  1. A video on using the Atelier debugger can be found here
  2. The Atelier documentation on using the debugger is here
  3. You can always reach out to InterSystems Support to work directly with an advisor (call +1 617-621-0700 or email support@intersystems.com)