Can't show fractional part as .0 when value is a whole number

Viewed 124

Here's the case:

uses
  System.JSON;
     
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  dd:Double;
  aJsonObj:TJSONObject;
begin
  dd := 100.0;
  aJsonObj := TJSONObject.Create(TJSONPair.Create('DecimalValue',TJSONNumber.Create(dd)));
  ShowMessage(aJsonObj.ToString);
end;

which shows

{"DecimalValue":100}

What I need is

{"DecimalValue":100.0}

I've tried to change JsonFormatSettings but I couldn't find a way to add the fractional part.

1 Answers

One of TJSONNumber constructors accepts a raw string value that will be used in resulting JSON string without further processing. It allows you to pre-format the value yourself:

procedure TForm1.Button1Click(Sender: TObject);
var
  dd: Double;
  aJsonObj: TJSONObject;
begin
  dd := 100.0;
  aJsonObj := TJSONObject.Create(
    TJSONPair.Create('DecimalValue', TJSONNumber.Create(FormatFloat('0.0###', dd, GetJSONFormat))));
  try
    ShowMessage(aJsonObj.ToString);
  finally
    aJsonObj.Free;
  end;
end;

Using the above snippet the value shows as:

{"DecimalValue":100.0}

You can even create 'whatever' as number:

aJsonObj := TJSONObject.Create(TJSONPair.Create('DecimalValue', TJSONNumber.Create('whatever')));

to get this (invalid) JSON:

{"DecimalValue":whatever}

Side note: you are responsible for releasing root JSON objects you create as they have no parent object to manage their lifetime. Use try..finally to Free the root object when you're done with it as you can see in the first code snippet. Too bad that the documentation itself tempts you not to cleanup.

Related