Reputation: 137
I am using Delphi Xe5 and I have a component that essentially uses IDTCPCLient (sockets) to talk with are server and retrieve data in the form of JSON. I have spared you all the connection code , etc. It works. The returned JSon works as well. The trouble I am having is converting my JSON into a StringList, which I then use to write out a list of values to a listbox and store the rest of the JSON data objects in the TSTrings OBjects property.
I have a number of funny things happen.
1.) I can't for the life of me get the List property to work properly. I use this list to store my JSON. A string value and then the entire object for each item in the list. You will notice that in the JSONToStringList method, I clear the stringlist (it is commented out, becuase when it isn't, my program hangs)
2.) I get dupplicate values in my list after calling the method more than once for multiple JSON sets needed
TConnector = class(TComponent)
private
{ Private declarations }
FList: TStrings;
procedure SetList(const Value: TStrings);
protected
{ Protected declarations }
public
{ Public declarations }
Constructor Create( AOwner : TComponent ); override;
Destructor Destroy; Override;
Procedure GenerateJSON;
Procedure JSONToStringList(aJSonKey: String);
published
{ Published declarations }
property List: TStrings Read FList Write SetList;
end;
Constructor TConnector.Create(AOwner: TComponent);
begin
inherited;
FList:= TStringList.Create(True);
end;
destructor TConnector.Destroy;
begin
if FList <> nil then
FreeAndNil(FList);
inherited;
end;
Procedure TConnector.GenerateJSON;
begin
if ResponseStream<>nil then
Begin
FreeAndNil(ResponseJSON_V);
ResponseJSON_V := TJSONObject.ParseJSONValue(StreamToArray(ResponseStream),0) as TJSONValue;
End;
end;
procedure TConnector.JSONToStringList(aJSonKey: String);
Var
zLJsonValue : TJSONValue;
zLJSONArray: TJSONArray;
zLJsonObject : TJSONObject;
zI : Integer;
begin
if ResponseJSON_V is TJSONArray then
begin
zLJSONArray:= ResponseJSON_V as TJSONArray;
zLJsonObject := zLJSONArray.Get(0) as TJSONObject;
end
else
if ResponseJSON_V is TJSONObject then
begin
zLJSONArray:= nil;
zLJsonObject := ResponseJSON_V as TJSONObject;
end
else
Exit;
if zLJSONArray<>nil then
begin
***//FList.Clear;***
for zLJsonValue in zLJSONArray do
begin
zLJsonObject := zLJsonValue as TJSONObject;
for zI := 0 to zLJsonObject.Size-1 do
begin
if zLJsonObject.Get(zI).JsonString.Value = aJSonKey then
begin
FList.AddObject(zLJsonObject.Get(zI).JSONValue.Value, zLJsonObject);
end;
end;
end;
end
else
begin
FList.Clear;
for zI := 0 to zLJsonObject.Size-1 do
begin
if zLJsonObject.Get(zI).JsonString.Value = aJSonKey then
FList.AddObject(zLJsonObject.Get(zI).JSONValue.Value, TJSONPair(zLJsonObject.Get(zI)));
end;
end;
end;
I hope this is all understandable. Please let me know if you need to see more. Please feel free to correct anything else you see bad in my code. I am always learning :) - thank you for your help
Upvotes: 3
Views: 4509
Reputation: 1
your code cannot work ... U define a param called "aJSonKey" and u call it "ResponseJSON_V " into the procedure.
Moreover u call this "ResponseJSON_V" into GenerateJSON proc when there is no property called that way.
Upvotes: 0
Reputation: 137
It turns out , that the FList property should not have been published, but rather made public instead. Which makes since, cause the list is only filled and emptied at runtime, never at design time.
TLiveConnector = class(TComponent)
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
List: TStrings;
published
end;
Not sure exactly why that is the case, but it seem to work just fine now
Calling List.Clear instead of FList.Clear;
Upvotes: 1
Reputation: 1593
If FList.Clear hangs then it's most likely memory corruption issue. First two thing I would suspect is that you have not called a constructor or that part of the memory has been overwritten by something else.
Can the duplicate values in the list be cause by the fact that you commented out FList.Clear. Anyway, I suggest using a debugger to see what goes in to the list or log everything added to/removed from the list. This should give you the idea where unneeded values in the list are coming from.
As a general advice you don't need to check if object is not nil before freeing it. The check is made in Free (or in the Free part of the FreeAndNil) anyway.
Upvotes: 1