Search code examples
delphiresponsefiremonkey

How to get the subitem value from a TRESTReponse in Delphi?


I need to get the subitem1 value of a LResponse that contains following JSON:

"Information": {
    "subitem1": "2011",
    "subitem2": "Test"
}

I am using this code to get the other values, it's working good, but when I try to get the Information, subitem1 or subitem2, it's returning a empty value.

var
  LClient: TRESTClient;
  LRequest: TRESTRequest;
  LResponse: TRESTResponse;
begin
  LClient := TRESTClient.Create(URL_API);
  try
    LRequest := TRESTRequest.Create(LClient);
    try
      LResponse := TRESTResponse.Create(LClient);
      try
        LRequest.Client := LClient;
        LRequest.Response := LResponse;
        LRequest.Method := rmGET;
        LRequest.Params.AddHeader('Authorization','Bearer '+FToken);
        LRequest.Params.ParameterByName('Authorization').Options := [poDoNotEncode];
        LRequest.Params.AddHeader('Accept', 'application/json');
        LRequest.Execute;

        LResponse.GetSimpleValue('subitem1', FLogradouro);
        { ... }

Solution

  • GetSimpleValue is only able to read top level properties of JSON in response. It is also extremely inefficient, because it parses JSON upon every call to the method.

    TRESTResponse already gives you access to parsed JSON via its JSONValue property. It allows you to query values within the whole structure using JSON path. Accessing JSONValue property will parse the response only once, but beware that it can return nil, if the response is empty or not a valid JSON.

    Another point is that you don't have to create TRestResponse yourself. It is automatically created in LRequest.Execute. With that said the code to access values in the returned JSON would be:

    if not Assigned(LRequest.Response.JSONValue) then
      raise Exception.Create('Invalid response.');
    ShowMessage(LRequest.Response.JSONValue.GetValue<string>('Information.subitem1'));
    

    You can use square brackets in JSON path as array accessor to access items by index:

    LRequest.Response.JSONValue.GetValue<string>('SomeStrings[0]');