Recent

Author Topic: Access violation with JSON  (Read 675 times)

johnmc

  • New Member
  • *
  • Posts: 47
Access violation with JSON
« on: August 09, 2022, 02:54:37 pm »
I have a small program that I am writing, it gets some information in JSON format from the web. I want to extract some of this info and put it in a database. So far I can download the data from the web and extract the data to a form. I read somewhere that you should free up any JSON data variables but when I do this it is causing access violations.

Any help would be appreciated.

John

Code: Pascal  [Select][+][-]
  1. unit Data;
  2.  
  3. {$mode ObjFPC}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, TypInfo,
  9.   fpjson, jsonparser;
  10.  
  11. type
  12.  
  13.   { TfrmExtractData }
  14.  
  15.   TfrmExtractData = class(TForm)
  16.     btnClose: TButton;
  17.     Edit1: TEdit;
  18.     Edit2: TEdit;
  19.     Edit3: TEdit;
  20.     Edit4: TEdit;
  21.     Edit5: TEdit;
  22.     Edit6: TEdit;
  23.     Edit7: TEdit;
  24.     GroupBox1: TGroupBox;
  25.     Label1: TLabel;
  26.     Label2: TLabel;
  27.     Label3: TLabel;
  28.     Label4: TLabel;
  29.     Label5: TLabel;
  30.     Label6: TLabel;
  31.     Label7: TLabel;
  32.     Label8: TLabel;
  33.     Label9: TLabel;
  34.     Memo1: TMemo;
  35.     Memo2: TMemo;
  36.     procedure btnCloseClick(Sender: TObject);
  37.     procedure FormActivate(Sender: TObject);
  38.     //function GetJSONData(JPath: string): string;
  39.   private
  40.     aEdit: array of TEdit;
  41.   public
  42.  
  43.   end;
  44.  
  45. var
  46.   frmExtractData: TfrmExtractData;
  47.  
  48. implementation
  49.  
  50. uses
  51.   main;
  52.  
  53. {$R *.lfm}
  54.  
  55. { TfrmExtractData }
  56.  
  57. procedure TfrmExtractData.FormActivate(Sender: TObject);
  58. var
  59.   J, O, P: TJSONData;
  60.   A: TJSONArray;
  61.   I: integer;
  62. begin
  63.   J := GetJSON(frmISBN.Memo1.Text);
  64.  
  65.   Edit1.Text := '';
  66.   P := J.FindPath('items[0].volumeInfo.title');
  67.   if (P <> nil) then Edit1.Text := P.AsString;
  68.  
  69.   Edit2.Text := '';
  70.   P := J.FindPath('items[0].volumeInfo.subtitle');
  71.   if (P <> nil) then Edit2.Text := P.AsString;
  72.  
  73.   Edit3.Text := '';
  74.   P := J.FindPath('items[0].volumeInfo.publisher');
  75.   if (P <> nil) then Edit3.Text := P.AsString;
  76.  
  77.   Edit4.Text := '';
  78.   P := J.FindPath('items[0].volumeInfo.publishedDate');
  79.   if (P <> nil) then Edit4.Text := P.AsString;
  80.  
  81.   Edit5.Text := '';
  82.   Edit6.Text := '';
  83.  
  84.   O := J.FindPath('items[0].volumeInfo.industryIdentifiers[0].type');
  85.   if (O <> nil) then
  86.   begin
  87.     P := J.FindPath('items[0].volumeInfo.industryIdentifiers[0].identifier');
  88.     case O.AsString of
  89.       'ISBN_10':
  90.       begin
  91.         if (P <> nil) then Edit5.Text := P.AsString;
  92.       end;
  93.       'ISBN_13':
  94.       begin
  95.         if (P <> nil) then Edit6.Text := P.AsString;
  96.       end;
  97.       'Other', 'OTHER':
  98.       begin
  99.         if (P <> nil) then Edit7.Text := P.AsString;
  100.       end;
  101.     end;
  102.   end;
  103.  
  104.   O := J.FindPath('items[0].volumeInfo.industryIdentifiers[1].type');
  105.   if (O <> nil) then
  106.   begin
  107.     P := J.FindPath('items[0].volumeInfo.industryIdentifiers[1].identifier');
  108.     case O.AsString of
  109.       'ISBN_10':
  110.       begin
  111.         if (P <> nil) then Edit5.Text := P.AsString;
  112.       end;
  113.       'ISBN_13':
  114.       begin
  115.         if (P <> nil) then Edit6.Text := P.AsString;
  116.       end;
  117.       'Other', 'OTHER':
  118.       begin
  119.         if (P <> nil) then Edit7.Text := P.AsString;
  120.       end;
  121.     end;
  122.   end;
  123.  
  124.   Memo1.Text := '';
  125.   P := J.FindPath('items[0].volumeInfo.description');
  126.   if (P <> nil) then Memo1.Text := P.AsString;
  127.  
  128.   Memo2.Text := '';
  129.   P := J.FindPath('items[0].searchInfo.textSnippet');
  130.   if (P <> nil) then Memo2.Text := P.AsString;
  131.  
  132.   O := J.FindPath('items[0].volumeInfo.authors');
  133.   if (O <> nil) and (O.JSONType = jtArray) then
  134.   begin
  135.     A := TJSONArray(O);
  136.     GroupBox1.Height := (A.Count * 25) + 25;
  137.     // Adjust the groupbox size to fit number of edit controls
  138.     //ShowMessage('1: Author Count ' + IntToStr(A.Count));
  139.     setlength(aEdit, A.Count);  // set the array size to hold the authors edit controls
  140.     for I := Low(aEdit) to High(aEdit) do  // for each edit control
  141.     begin
  142.       aEdit[I] := TEdit.Create(Self);  // create edit control and add to array
  143.       with aEdit[I] do
  144.       begin
  145.         Parent := GroupBox1;    // Define the parent object
  146.         Caption := J.FindPath('items[0].volumeInfo.authors[' +
  147.           IntToStr(I) + ']').AsString;
  148.         // Some text to show
  149.         Anchors := [akTop, akLeft, akRight];      // Define which sides will be anchored
  150.  
  151.         AnchorSide[akLeft].Control := Parent;     // Anchor left side to parent
  152.         AnchorSide[akLeft].Side := asrLeft;
  153.         // Anchor left side of object to left side of parent
  154.  
  155.         AnchorSide[akRight].Control := Parent;    // ditto for right
  156.         AnchorSide[akRight].Side := asrRight;
  157.  
  158.         BorderSpacing.Left := 4;
  159.         BorderSpacing.Right := 4;
  160.         BorderSpacing.Bottom := 2;
  161.         BorderSpacing.Top := 2;
  162.  
  163.         if I = 0 then
  164.         begin
  165.           // for the first edit control we use the groupbox for an anchor
  166.           AnchorSide[akTop].Control := Parent;   // anchor top to parent
  167.           AnchorSide[akTop].Side := asrTop;      // anchor top to top
  168.         end
  169.         else
  170.         begin
  171.           // for all subsequent items we anchor to the item above
  172.           AnchorSide[akTop].Control := aEdit[I - 1]; // anchor to edit control above
  173.           AnchorSide[akTop].Side := asrBottom;   // top of current to bottom of one above
  174.  
  175.         end;
  176.       end;
  177.     end;
  178.  
  179.   end;
  180.   //ShowMessage('2: The End ');
  181.  
  182.   J.Free;
  183.   O.Free;
  184.   P.Free;
  185. end;
  186.  
  187. procedure TfrmExtractData.btnCloseClick(Sender: TObject);
  188. begin
  189.   Close;
  190. end;
  191.  
  192. end.
  193.  

lainz

  • Hero Member
  • *****
  • Posts: 4462
    • https://lainz.github.io/
Re: Access violation with JSON
« Reply #1 on: August 09, 2022, 03:04:05 pm »
Please put a compilable example and include the JSON data.

In any case try to free only this variable J:

Code: Pascal  [Select][+][-]
  1.   J := GetJSON(frmISBN.Memo1.Text);
« Last Edit: August 09, 2022, 03:17:51 pm by lainz »

Zvoni

  • Hero Member
  • *****
  • Posts: 2319
Re: Access violation with JSON
« Reply #2 on: August 09, 2022, 03:20:54 pm »
You do realize that TJSONData is an abstract (Base)-Class?
https://www.freepascal.org/docs-html/fcl/fpjson/tjsondata.html
Quote
TJSONData is an abstract class which introduces all properties and methods needed to work with JSON-based data. It should never be instantiated.
And...... You try to free something you've never created.
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

lainz

  • Hero Member
  • *****
  • Posts: 4462
    • https://lainz.github.io/
Re: Access violation with JSON
« Reply #3 on: August 09, 2022, 05:37:31 pm »
You do realize that TJSONData is an abstract (Base)-Class?
https://www.freepascal.org/docs-html/fcl/fpjson/tjsondata.html
Quote
TJSONData is an abstract class which introduces all properties and methods needed to work with JSON-based data. It should never be instantiated.
And...... You try to free something you've never created.

Indeed. Try using JSONObject.

But my advice is correct too, you only need to free the object createad with GetJSON, the others are just pointers that are also free when you free the main thing.

johnmc

  • New Member
  • *
  • Posts: 47
Re: Access violation with JSON
« Reply #4 on: August 09, 2022, 06:36:51 pm »
Thanks thats looks like where I'm going wrong.

John

 

TinyPortal © 2005-2018