0

I am new to JSON. I have the following JSON data and I don't know how to read the transaction object's id and amount values.

{
  "errorCode": 0,
  "errorMessage": "ok",
  "platform": 4,
  "order": {
    "id": "3425",
    "description": "test api",
    "amount": 1.39,
    "currency": "RON",
    "billing": {
      "country": null,
      "county": null,
      "city": null,
      "address": "address",
      "postal_code": null,
      "first_name": "fn",
      "last_name": "ln",
      "phone": "0000000000",
      "email": "me@mobilpay.com"
    },
    "shipping": null,
    "installments": null,
    "installments_sel": null,
    "bonuspoints": null,
    "products": {
      "item": {
        "id": null,
        "name": null,
        "description": null,
        "info": null,
        "group": null,
        "amount": null,
        "currency": null,
        "quantity": null,
        "vat": null
      }
    },
  "hash": "1BB262DEE09B15ED98B777A27740E16B1F00004E",
  "transaction": {
    "id": "461512",
    "amount": 1.39,
    "currency": "RON",
    "paymentUrl": "/qp/BdKQsV1d-DsGz0e-4Bkq2e",
    "current_payment_count": null
  },
  "params": null
}

I can read the errorCode and the errorMessage, but I don't know how to access the transaction id.

This is the code I have so far:

function TuDm_Athlos.ReadJson(ContentStr: TStream; var Order: TOrder): Boolean;
var
  workJson : ISuperObject;
begin
  Result := False;
  workJson := TSuperObject.ParseStream(ContentStr,False);
  Order.ErrorCode := StrToInt(workJson.S['errorCode']);
  order.ErrorMessage := workJson.S['errorMessage'];
  for workJson in workJson.O['transaction'] do
  begin
    Order.id := workJson.S['id'];
  end;
  Result := True;
end; 
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Vlad Costin
  • 61
  • 1
  • 10
  • You have to start by writing some Delphi code. You don't appear to have any. We aren't a service to do that for you. Start with the documentation. Don't start by trying to parse this document. Walk before you run. Start by parsing small simple documents. Gradually build up the complexity. The documentation has lots of examples. Please try harder. – David Heffernan Aug 14 '17 at 08:48
  • `function TuDm_Athlos.ReadJson(ContentStr: TStream; var Order: TOrder): Boolean; var workJson : ISuperObject; begin Result := False; workJson := TSuperObject.ParseStream(ContentStr,False); Order.ErrorCode := StrToInt(workJson.S['errorCode']); order.ErrorMessage := workJson.S['errorMessage']; for workJson in workJson.O['transaction'] do begin Order.id := workJson.S['id']; end; Result := True; end;` – Vlad Costin Aug 14 '17 at 08:51
  • 1
    That's not trying harder. That's plugging on in the same haphazard fashion. Slow down, and think harder about your problem. Read my entire comment, and then heed its advice. Back to basics. Start at the beginning of the documentation for the library. – David Heffernan Aug 14 '17 at 08:57
  • But `for workJson in workJson.O['transaction']` looks dubious. I think you'll need a different variable for the loop variable. Don't think you can get away with just a single `ISuperObject` variable. – David Heffernan Aug 14 '17 at 09:06

3 Answers3

2

You need to go deeper in the JSON object hierarchy. Based on code you've posted in comment:

function TuDm_Athlos.ReadJson(ContentStr: TStream; var Order: TOrder): Boolean;
var
  JSON: ISuperObject;
  Order: ISuperObject;
  Trans: ISuperObject;
begin
  Result := False;

  JSON := TSuperObject.ParseStream(ContentStr, False);
  if not Assigned(JSON) then
    Exit;

  Order := JSON.O['order'];
  if not Assigned(Order) then
    Exit;

  Trans := Order.O['transaction'];
  if not Assigned(Trans) then
    Exit;

  Order.ID := Trans.I['id'];
  Order.Amount := Trans.D['amount'];
  Order.ErrorCode := JSON.I['errorCode'];
  Order.ErrorMessage := JSON.S['errorMessage'];

  Result := True;
end;
Victoria
  • 7,822
  • 2
  • 21
  • 44
0

I know this is a pretty old post, but I ran into the same thing. If you're a diligent developer, you might have range checking and overflow checking turned on while you're in development. The version of SuperObject you're working with may use a Hash for fast key comparisons that's defined as Cardinal. The Hash method assumes it can overflow the Cardinal type, but that overflow will trip range and overflow checking. To do it properly, you can modify the unit to use Int64 in place of Cardinal, then in the Hash method mask the calculated value to cut it back down to 32 bits, as in:

h := ( h*129 + ord(k[i]) + $9e370001 ) and $FFFFFFFF;

Same effect, no overflow.

Todd Grigsby
  • 764
  • 6
  • 7
0

Just make variable h: UInt64 and no AV by overflow.