The
Progress.Json.ObjectModel.JsonObject class, together with the other classes in the OpenEdge JSON object model, can be useful when an application front end uses a JavaScript framework with JSON support. Since OpenEdge 11.5.1, a JSON object can be used to build a request with the new OpenEdge HTTP client.
The sample code in this Article shows a round trip a
TEMP-TABLE to a
JsonObject and back to the
TEMP-TABLE:
- Fills a temp-table with selected records from the Customer table of the Sports2000 sample database.
- Instantiates a Progress.Json.ObjectModel.JsonObject.
- Fills the JsonObject with data from the temp-table records using the JsonObject:Read() method.
- Serializes the JsonObject to a LONGCHAR using the JsonObject:Write() method and passes it to an internal procedure that zeroes out each customer's balance. In an actual application the serialized JSON object might, for example, be passed to a remote service in an HTTP request.
- Replaces the modified records from the LONGCHAR output using the temp-table's READ-JSON() method. This is possible because the JSON in the LONGCHAR originated from the temp-table records using ABL, so it is guaranteed to be in a format that READ-JSON() can parse.
- Displays data from the temp-table to verify the round trip.
- This is possible because the temp-table has a defined schema. If the ABL virtual machine (AVM) must parse an incoming JSON string into a dynamic temp-table or ProDataSet (that is, one that does not already have a schema), the AVM must infer the schema from the data. In such a case the data objects on both sides of a transaction may not have identical schema. In addition, metadata such as key fields are lost in the serialization to and from JSON.
USING Progress.Json.ObjectModel.*.
/* ttCust definition */
DEFINE TEMP-TABLE ttCust
FIELD CustNum LIKE Customer.CustNum
FIELD Country LIKE Customer.Country
FIELD Name LIKE Customer.Name
FIELD Address LIKE Customer.Address
FIELD Address2 LIKE Customer.Address2
FIELD City LIKE Customer.City
FIELD State LIKE Customer.State
FIELD PostalCode LIKE Customer.PostalCode
FIELD Contact LIKE Customer.Contact
FIELD Phone LIKE Customer.Phone
FIELD SalesRep LIKE Customer.SalesRep
FIELD CreditLimit LIKE Customer.CreditLimit
FIELD Balance LIKE Customer.Balance
FIELD Terms LIKE Customer.Terms
FIELD Discount LIKE Customer.Discount
FIELD Comments LIKE Customer.Comments
FIELD Fax LIKE Customer.Fax
FIELD EmailAddress LIKE Customer.EmailAddress
INDEX CountryPost Country PostalCode
INDEX Comments IS WORD-INDEX Comments
INDEX CustNum IS UNIQUE PRIMARY CustNum
INDEX NAME NAME
INDEX SalesRep SalesRep
.
DEFINE VARIABLE httCust AS HANDLE NO-UNDO.
DEFINE VARIABLE oJson AS JsonObject NO-UNDO.
DEFINE VARIABLE lReturnValue AS LOGICAL NO-UNDO.
DEFINE VARIABLE lcJson AS LONGCHAR NO-UNDO.
httCust = TEMP-TABLE ttCust:HANDLE.
/* Fill temp-table from database */
FOR EACH Customer WHERE CustNum < 4:
CREATE ttCust.
BUFFER-COPY Customer TO ttCust.
END.
/* Create new JsonObject */
oJson = NEW JsonObject().
/* Fill with properties representing each field in each record of temp-table */
lReturnValue = oJson:Read( httCust ).
/* Serialize the JsonObject to a LONGCHAR variable and pass it to an internal procedure that zeroes out the Balance field for each customer. In an actual application, work like that done in the internal procedure might be done by a remote service.
*/
oJson:Write(lcJson).
RUN forgiveBalance(INPUT-OUTPUT lcJson).
/* Update the temp-table records from the serialized JSON */
httCust:READ-JSON ("LONGCHAR", lcJson, "REPLACE").
/* Display the updated temp-table records */
FOR EACH ttCust:
DISPLAY ttCust.CustNum ttCust.Name ttCust.Balance.
END.
/* This internal procedure substitutes in this example for a remote service that might typically accept JSON-formatted requests and return JSON-formatted responses. It also serves as a further example of how to parse, get and set JSON elements using the Progres.Json classes.
*/
PROCEDURE forgiveBalance:
DEFINE INPUT-OUTPUT PARAMETER piolcJson AS LONGCHAR NO-UNDO.
DEFINE VARIABLE oParser AS ObjectModelParser NO-UNDO.
DEFINE VARIABLE oObject AS JsonObject NO-UNDO.
DEFINE VARIABLE oArray AS JsonArray NO-UNDO.
DEFINE VARIABLE i AS INTEGER NO-UNDO.
DEFINE VARIABLE n AS INTEGER NO-UNDO.
DEFINE VARIABLE oRecord AS JsonObject NO-UNDO.
oParser = NEW ObjectModelParser().
DO ON ERROR UNDO, THROW:
oObject = CAST(oParser:Parse(INPUT piolcJson), JsonObject).
oArray = oObject:GetJsonArray("ttCust").
n = oArray:Length.
DO i = 1 TO n:
oRecord = oArray:GetJsonObject(i).
IF oRecord:Has("Balance")
THEN oRecord:Set("Balance", 0.0).
oArray:Set(i, oRecord).
END.
oObject:Set("ttCust", oArray).
oObject:Write(piolcJson).
CATCH e AS Progress.Lang.Error:
MESSAGE "forgiveBalance: Parameter not in expected format, exiting..."
VIEW-AS ALERT-BOX.
QUIT.
END.
END.
END PROCEDURE.