How to retrieve Data from JSON file (Web Request)? lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- MrMaxMusterman · 2021-05-21 21:46 I have a question concerning retrieving data from a JSON file with i get by a URL request. I already have a few code snippets together from other forum articles (see below) Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.Button1Click(Sender: TObject);var  Http:TFPHttpClient;  Content:String;  Json:TJSONData;  Lat:string;begin   Http:=TFPHttpClient.Create(Nil);   try     Content:=Http.Get('https://www.mywebsite.com');     JSON:=GetJSON(Content);     try       //Retrieving Data from JSON     finally     end;   finally   end;end; My question now becomes how i'm now able to retrieve data from the JSON File. Down below, i have the whole JSON File which is displayed when requesting the desired URL Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {   "results" : [      {         "address_components" : [            {             "long_name" : "20",               "short_name" : "20",             "types" : [ "street_number" ]            },            {             "long_name" : "West 34th Street",               "short_name" : "W 34th St",               "types" : [ "route" ]            },          {               "long_name" : "Manhattan",               "short_name" : "Manhattan",               "types" : [ "political", "sublocality", "sublocality_level_1" ]            },            {             "long_name" : "New York",               "short_name" : "New York",               "types" : [ "locality", "political" ]            },            {               "long_name" : "New York County",             "short_name" : "New York County",               "types" : [ "administrative_area_level_2", "political" ]            },            {               "long_name" : "New York",               "short_name" : "NY",               "types" : [ "administrative_area_level_1", "political" ]            },            {               "long_name" : "USA",               "short_name" : "US",               "types" : [ "country", "political" ]            },            {               "long_name" : "10118",               "short_name" : "10118",             "types" : [ "postal_code" ]            }         ],         "formatted_address" : "20 W 34th St, New York, NY 10118, USA",       "geometry" : {            "location" : {               "lat" : 40.748558,               "lng" : -73.9857578            },            "location_type" : "ROOFTOP",            "viewport" : {               "northeast" : {                  "lat" : 40.74990698029149,                "lng" : -73.98440881970849               },               "southwest" : {                  "lat" : 40.74720901970849,                "lng" : -73.98710678029151               }            }         },         "place_id" : "ChIJr92XCKlZwokRIy2j_7Rb2V8",         "plus_code" : {            "compound_code" : "P2X7+CM New York City, New York, USA",            "global_code" : "87G8P2X7+CM"         },       "types" : [ "street_address" ]      }   ],   "status" : "OK"} In my case, I want to retrieve the "lat" and "lng" values out of the JSON File. I would really appreciate your help with this. Thanks in advance. ---------------------------------------------------------------------- zamronypj · 2021-05-21 23:43 https://wiki.freepascal.org/fcl-json Code: [Select]lat := json.FindPath('results[0].geometry.location.lat').AsFloat; lon := json.FindPath('results[0].geometry.location.lng').AsFloat; ---------------------------------------------------------------------- engkin · 2021-05-22 00:02 Or: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var  location:TJSONObject;  lat,lng:Single;...  location:=TJSONObject(Json.FindPath('results[0].geometry.location'));  lat:=location.Floats['lat'];  lng:=location.Floats['lng']; ---------------------------------------------------------------------- MrMaxMusterman · 2021-05-22 08:47 First off, thanks for your help. I tried implementing all this but sadly, i always get EHTTPClient Exeption Class due to Status Code 400. Idk why but just to make things clear, its an https website with a JSON File being hosted on. Did I maybe forget something under the "uses" category or so? Here is my full source code: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, fphttpclient, fpjson, jsonparser, opensslsockets; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    Edit1: TEdit;    Label1: TLabel;    Label2: TLabel;    procedure Button1Click(Sender: TObject);  private   public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);var  Client:TFPHttpClient;  Content:String;  Json:TJSONData;  Lat,Lng:string;  Location:string;begin   Client:=TFPHttpClient.Create(Nil);   Client.AllowRedirect:=true;   Location:=Edit1.Text;   try     Content:=Client.Get('https://mywebsite'+Location+'APIKEY');     JSON:=GetJSON(Content);     try       Lat:=json.FindPath('results[0].geometry.location.lat').AsString;     Lng:=json.FindPath('results[0].geometry.location.lng').AsString;     finally     end;   finally   end;   Label1.Caption:=Lat;   Label2.Caption:=Lng;end; end. ---------------------------------------------------------------------- engkin · 2021-05-22 12:37 I don't see a missing unit. HTTP code 400 means the server is not happy with your request. Something is wrong with the request itself. Sometimes the server sends a message to explain more. Put the request you are sending here. Obsecure any sensitive data with #### Edit: Probably it wants a User Agent. Try adding: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   Client.AddHeader('User-Agent', 'Mozilla/5.0 (compatible; fpweb)');  Client.AddHeader('Content-Type', 'application/json'); right after Client.AllowRedirect ---------------------------------------------------------------------- MrMaxMusterman · 2021-05-22 13:17 Sadly, your idea with adding a user agent etc. didnt work out. Here is my full source code with the actual request: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, fphttpclient, fpjson, jsonparser, opensslsockets; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    Button2: TButton;    Edit1: TEdit;    Label1: TLabel;    Label2: TLabel;    procedure Button1Click(Sender: TObject);  private   public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);var  Client:TFPHttpClient;  Content:String;  Json:TJSONData;  Lat,Lng:Single;  Location:string;begin   Client:=TFPHttpClient.Create(Nil);   Client.AllowRedirect:=true;   Client.AddHeader('User-Agent', 'Mozilla/5.0 (compatible; fpweb)');   Client.AddHeader('Content-Type', 'application/json');   Location:=Edit1.Text;   try     Content:=Client .Get('https://maps.googleapis.com/maps/api/geocode/json?address= '+Location+' &key={MyAPIKey}');     JSON:=GetJSON(Content);     try     Lat:=json.FindPath('results[0].geometry.location.lat').AsFloat;     Lng:=json.FindPath('results[0].geometry.location.lng').AsFloat;     finally     end;   finally   end;   Label1.Caption:=FloatToStr(Lat);   Label2.Caption:=FloatToStr(Lng);end;end.  The only thing i put out of this source code is my api key from google. It isnt the problem though cause if im actually using the link (so my request including an adress, which can be formatted in any way possible) in my browser, ill get the full json file. Can you mabye tell me how i can gain more info on the error message itself? I only get "Project project1 got Exeption Class EHTTPPClient with following message: Unexpected response status code:400" (translated) ---------------------------------------------------------------------- engkin · 2021-05-22 13:52 Since it works in your browser, get the request your browser is sending. Search for an Add On, Extension, or Plug In for your browser that would let you see the request including the headers. Then simply replicate it. Search for "HTTP 400": Here is one result Edit: I bet there is a cookie in your browser that needs to be sent as well. You had the authorize your browser at somepoint. ---------------------------------------------------------------------- MrMaxMusterman · 2021-05-22 14:08 I actually found out why the program wasnt working the whole time... The problem was that for some reason, Lazarus didnt convert spaces between each Adress Info (e.g. Street Name and Street Number) that the user would type into the edit box into a new request with no spaces whatsoever. Is there maybe a way to replace all empty spaces in a string (userinput) with something else (e.g. commas)? ---------------------------------------------------------------------- engkin · 2021-05-22 14:37 Try using EncodeURLElement? It turns 123 Street, City, State 12345 into 123%20Street,%20City,%20State%2012345 ---------------------------------------------------------------------- MrMaxMusterman · 2021-05-22 16:24 Thank you so much!! Now everything works as intended.