Accessing JSON data from Open Weater Maps API lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- CieloInvernale · 2016-12-19 21:41 I'm trying to interface with OpenWeaterMaps API (http://openweathermap.org/). All API options and parameters are fully explained, anyway I've got troubles when I came to the Lazarus part (sorry, I'm a newbye with Lazarus...). The application is simple: retrieve JSON data from the appropriate URL then parse each part as a simple string. My program 'till now tries to retrieve the "main" data in JSON structure ("Clouds" in the following example JSON code - notice that there are 2 different "main" nodes in the response, I'm trying to access the first one nested within "weather" or, in other words, "weather->main:Clouds"). JSON API's response sample: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i {"coord":{" lon":145.77,"lat":- 16.92},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"cmc stations","main":{"temp":293.25,"pr essure":1019,"humidity":83,"temp_min":289.82,"temp_max":295.37},"wind" :{"speed":5.1,"deg":150},"clouds":{"all":75},"rain":{"3h":3},"dt":1435 658272,"sys":{"type":1,"id":8166,"message":0.0166,"country":"AU","sunr ise":1435610796,"sunset":1435650870},"id":2172797,"name":"Cairns","cod ":200}  My code so far (MYCITYID and MYAPPID are placeholders for the real keys, obviously not to be published here...): 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, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, fphttpclient,  fpjson, jsonparser; type   { TForm1 }   TForm1 = class(TForm)    Memo1: TMemo;    procedure FormCreate(Sender: TObject);  private    { private declarations }  public    { public declarations }  end; var  Form1: TForm1;  jData : TJSONData;  jObject : TJSONObject;  wheater_main : String; implementation {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject);begin  jData := GetJSON(TFPHTTPClie nt.SimpleGet('http://api.openweathermap.org/data/2.5/weather?id=MYCITY ID&appid=MYAPPID'));   wheater_main := jData.FindPath('main').AsString;   Memo1.Lines.Clear;   Memo1.Lines.Add(wheater_main); end; end.  Code compiles correctly and an executable is produced, anyway when I launch it it returns the following error: QuoteCannot convert data from object value. Any idea about what's wrong with my code?? Thanks in advance for your time and attention. ---------------------------------------------------------------------- molly · 2016-12-20 00:15 The path main is not a complete end path, rather a path to a more complex (sub)structure in json format. Either access the full path directly by supplying that full path (e.g. "main.pressure") or retrieve path "main" into a separate JSONData structure (jData2 := jData.FindPath('main')) and then search for the path e.g. "pressure"). edit: if your aim is really to get a string representation of the main json data structure then you can use jData.FindPath('main').AsJSon; ---------------------------------------------------------------------- bytebites · 2016-12-20 04:10 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 jData.FindPath('weather').Items[0].FindPath('main').AsString ---------------------------------------------------------------------- molly · 2016-12-20 04:31 Ah, good point bytebites.  I overlooked that there were multiple "main"'s  In that case: 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 Writeln('weather[0].main = ' , jData.FindPath('weather[0].main').AsString); ---------------------------------------------------------------------- magleft · 2023-09-29 10:06 I tried downloading data from openweathermap. The raw data is in the form shown 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 {"cod":"200 ","message":0,"cnt":40,"list":[{"dt":1695988800,"main":{"temp":300.37, "feels_like":300.12,"temp_min":300.37,"temp_max":301.04,"pressure":101 8,"sea_level":1018,"grnd_level":1015,"humidity":39,"temp_kf":- 0.67},"weather":[{"id":500,"main":"Rain","description":"light rain","i con":"10d"}],"clouds":{"all":31},"wind":{"speed":3.12,"deg":231,"gust" :2.49},"visibility":10000,"pop":0.22,"rain":{"3h":0.17},"sys":{"pod":" d"},"dt_txt":"2023-09-29 12:00:00"},{"dt":1695999600,"main":{"temp":29 7.16,"feels_like":297.13,"temp_min":295.72,"temp_max":297.16,"pressure ":1018,"sea_level":1018,"grnd_level":1016,"humidity":58,"temp_kf":1.44 },"weather":[{"id":500,"main":"Rain","description":"light rain","icon" :"10d"}],"clouds":{"all":41},"wind":{"speed":2.08,"deg":357,"gust":4.8 },"visibility":10000,"pop":0.71,"rain":{"3h":1.47},"sys":{"pod":"d"}," dt_txt":"2023-09-29 15:00:00"},{"dt":1696010400,"main":{"temp":291.93, "feels_like":292,"temp_min":291.93,"temp_max":291.93,"pressure":1019," sea_level":1019,"grnd_level":1017,"humidity":82,"temp_kf":0},"weather" :[{"id":501,"main":"Rain","description":"moderate rain","icon":"10n"}] ,"clouds":{"all":54},"wind":{"speed":2.85,"deg":15,"gust":4.62},"visib ility":10000,"pop":0.9,"rain":{"3h":3.45},"sys":{"pod":"n"},"dt_txt":" 2023-09-29 18:00:00"},{"dt":1696021200,"main":{"temp":292.09,"feels_li ke":292.02,"temp_min":292.09,"temp_max":292.09,"pressure":1019,"sea_le vel":1019,"grnd_level":1017,"humidity":76,"temp_kf":0},"weather":[{"id ":500,"main":"Rain","description":"light rain","icon":"10n"}],"clouds" :{"all":38},"wind":{"speed":1.82,"deg":57,"gust":2.37},"visibility":10 000,"pop":0.6,"rain":{"3h":0.16},"sys":{"pod":"n"},"dt_txt":"2023-09- 29 21:00:00"},{"dt":1696032000,"main":{"temp":292.82,"feels_like":292. 72,"temp_min":292.82,"temp_max":292.82,"pressure":1018,"sea_level":101 8,"grnd_level":1016,"humidity":72,"temp_kf":0},"weather":[{"id":803,"m ain":"Clouds","description":"broken clouds","icon":"04n"}],"clouds":{" all":68},"wind":{"speed":1.55,"deg":21,"gust":1.54},"visibility":10000 ,"pop":0.34,"sys":{"pod":"n"},"dt_txt":"2023-09-30 00:00:00"},{"dt":16 96042800,"main":{"temp":292.45,"feels_like":292.32,"temp_min":292.45," temp_max":292.45,"pressure":1017,"sea_level":1017,"grnd_level":1015,"h umidity":72,"temp_kf":0},"weather":[{"id":500,"main":"Rain","descripti on":"light rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed":1 .55,"deg":35,"gust":1.52},"visibility":10000,"pop":0.37,"rain":{"3h":0 .11},"sys":{"pod":"n"},"dt_txt":"2023-09-30 03:00:00"},  I tried the following code without success: 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   Http := TFPHTTPClient.Create(nil);   try     Http.IOTimeout := 1000;     Http.AllowRedirect := True;     jData := GetJSON(Http.Get(urltext));     Memo1.Lines.Add(jData.FindPath('list.items[0].main.items.temp').AsS tring);    Json.Free;   finally     Http.Free;   end;   Can anyone help? ---------------------------------------------------------------------- paweld · 2023-09-29 10:25 In your case, the path should look like this: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 Memo1.Lines.Add(jData.FindPath('list[0].main.temp').AsString);clearer example: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 uses  fpjson; procedure TForm1.Button1Click(Sender: TObject);const  json = ' {"cod":"200","message":0,"cnt":40,"list":[{"dt":1695988800,"main":{"te mp":300.37,"feels_like":300.12,"temp_min":300.37,"temp_max":301.04,"pr essure":1018,"sea_level":1018,"grnd_level":1015,"humidity":39,"temp_kf ":-0.67},"weather":[{"id":500,"main":"Rain","description":"light rain" ,"icon":"10d"}],"clouds":{"all":31},"wind":{"speed":3.12,"deg":231,"gu st":2.49},"visibility":10000,"pop":0.22,"rain":{"3h":0.17},"sys":{"pod ":"d"},"dt_txt":"2023-09-29 12:00:00"},{"dt":1695999600,"main":{"temp" :297.16,"feels_like":297.13,"temp_min":295.72,"temp_max":297.16,"press ure":1018,"sea_level":1018,"grnd_level":1016,"humidity":58,"temp_kf":1 .44},"weather":[{"id":500,"main":"Rain","description":"light rain","ic on":"10d"}],"clouds":{"all":41},"wind":{"speed":2.08,"deg":357,"gust": 4.8},"visibility":10000,"pop":0.71,"rain":{"3h":1.47},"sys":{"pod":"d" },"dt_txt":"2023-09-29 15:00:00"},{"dt":1696010400,"main":{"temp":291. 93,"feels_like":292,"temp_min":291.93,"temp_max":291.93,"pressure":101 9,"sea_level":1019,"grnd_level":1017,"humidity":82,"temp_kf":0},"weath er":[{"id":501,"main":"Rain","description":"moderate rain","icon":"10n "}],"clouds":{"all":54},"wind":{"speed":2.85,"deg":15,"gust":4.62},"vi sibility":10000,"pop":0.9,"rain":{"3h":3.45},"sys":{"pod":"n"},"dt_txt ":"2023-09-29 18:00:00"},{"dt":1696021200,"main":{"temp":292.09,"feels _like":292.02,"temp_min":292.09,"temp_max":292.09,"pressure":1019,"sea _level":1019,"grnd_level":1017,"humidity":76,"temp_kf":0},"weather":[{ "id":500,"main":"Rain","description":"light rain","icon":"10n"}],"clou ds":{"all":38},"wind":{"speed":1.82,"deg":57,"gust":2.37},"visibility" :10000,"pop":0.6,"rain":{"3h":0.16},"sys":{"pod":"n"},"dt_txt":"2023- 09-29 21:00:00"},{"dt":1696032000,"main":{"temp":292.82,"feels_like":2 92.72,"temp_min":292.82,"temp_max":292.82,"pressure":1018,"sea_level": 1018,"grnd_level":1016,"humidity":72,"temp_kf":0},"weather":[{"id":803 ,"main":"Clouds","description":"broken clouds","icon":"04n"}],"clouds" :{"all":68},"wind":{"speed":1.55,"deg":21,"gust":1.54},"visibility":10 000,"pop":0.34,"sys":{"pod":"n"},"dt_txt":"2023-09-30 00:00:00"},{"dt" :1696042800,"main":{"temp":292.45,"feels_like":292.32,"temp_min":292.4 5,"temp_max":292.45,"pressure":1017,"sea_level":1017,"grnd_level":1015 ,"humidity":72,"temp_kf":0},"weather":[{"id":500,"main":"Rain","descri ption":"light rain","icon":"10n"}],"clouds":{"all":100},"wind":{"speed ":1.55,"deg":35,"gust":1.52},"visibility":10000,"pop":0.37,"rain":{"3h ":0.11},"sys":{"pod":"n"},"dt_txt":"2023-09-30 03:00:00"}]}';var  jd: TJSONData;  ja: TJSONArray;  jo: TJSONObject;  i: Integer;begin  jd := GetJSON(json);  if jd.FindPath('list') <> nil then  begin    ja := TJSONArray(jd.FindPath('list'));    if ja.Count > 0 then    begin    jo := TJSONObject(ja.Items[0]);      if jo.FindPath('main.temp') <> nil then        Memo1.Lines.Add(Format('%5d     %f', [i, jo.FindPath('main.temp').AsFloat]));    end;    ////or all items    //for i := 0 to ja.Count - 1 do    //begin    //  jo := TJSONObject(ja.Items[i]);    //  if jo.FindPath('main.temp') <> nil then    //    Memo1.Lines.Add(Format('%5d     %f', [i, jo.FindPath('main.temp').AsFloat]));    //end;  end;  jd.Free;end; ---------------------------------------------------------------------- TRon · 2023-09-29 10:31 Also note that you get a list of 40! entries. It is a forecast based upon this. I have no idea if the data in the list is sorted in a particular order (I assume it is returned with a sort on dt values). ---------------------------------------------------------------------- magleft · 2023-09-29 11:39 Indeed, it concerns 40 registrations. I modified the example paweld sent a bit, but it doesn't work. What am I doing wrong; 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 TFwheather.Button2Click(Sender: TObject);var  Http: TFPHTTPClient;  info, Content: string;  Json: TJSONData;  JsonObject: TJSONObject;  wheater_main : String;  jdata:TJSONData;  enum: TJSONEnum;  jd: TJSONData;  ja: TJSONArray;  jo: TJSONObject;  i: Integer;  urltext :String;begin  urltext:='api.openweathermap.org/data/2.5/forecast?lat= 39.1520282768&lon=20,9768486023&APPID=45a17f4586f55c714ae04d9c36e8a834 ' ;//{API key}  try  Http.IOTimeout := 1000;  Http.AllowRedirect := True;  jd := GetJSON(Http.Get(urltext));  if jd.FindPath('list') <> nil then  begin    ja := TJSONArray(jd.FindPath('list'));    if ja.Count > 0 then {   begin      jo := TJSONObject(ja.Items[0]);      if jo.FindPath('main.temp') <> nil then        Memo1.Lines.Add(Format('%5d     %f', [i, jo.FindPath('main.temp').AsFloat]));    end;}    ////or all items    for i := 0 to ja.Count - 1 do    begin      jo := TJSONObject(ja.Items[i]);      if jo.FindPath('main.temp') <> nil then        Memo1.Lines.Add(Format('%5d     %f', [i, jo.FindPath('main.temp').AsFloat]));    end;  end;   finally  jd.Free;  end;end; ---------------------------------------------------------------------- rvk · 2023-09-29 11:48 Quote from: magleft on September 29, 2023, 01:39:20 pmIndeed, it concerns 40 registrations. I modified the example paweld sent a bit, but it doesn't work. What am I doing wrong;Well. The first thing you are doing wrong is not telling us what the problem is  Error message????? Crash???? What does happen? Second... looking at your code... I see a http declaration in the procedure but I don't see you creating the object itself. So you are missing a 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 http := TFPHTTPClient.Create(nil);try  //...finally  http.free;end;  Also... urltext needs to contain a protocol (so https:// in front of it). And don't forget to include opensslsockets in your uses. ---------------------------------------------------------------------- paweld · 2023-09-29 12:11 First of all, don't share your API key - they can block your access.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 uses  fpjson, fphttpclient, opensslsockets; procedure TForm1.Button1Click(Sender: TObject);const  url = 'https://api.openwea thermap.org/data/2.5/forecast?lat=39.1520282768&lon=20,9768486023&APPI D={yourAPPID}';var  jd: TJSONData;  ja: TJSONArray;  jo: TJSONObject;  i: Integer;  hc: TFPHttpClient;  json: String;begin  hc := TFPHttpClient.Create(nil);  hc.AllowRedirect := True;  try    json := hc.Get(url);    if json <> '' then    begin      jd := GetJSON(json);      if jd.FindPath('list') <> nil then      begin        ja := TJSONArray(jd.FindPath('list'));        for i := 0 to ja.Count - 1 do        begin          jo := TJSONObject(ja.Items[i]);          if jo.FindPath('main.temp') <> nil then            Memo1.Lines.Add(Format('%5d     %f', [i, jo.FindPath('main.temp').AsFloat]));        end;      end;      jd.Free;    end    else      ShowMessage('Empty response');  finally  hc.Free;  end;end; ---------------------------------------------------------------------- magleft · 2023-09-29 12:22 I would like to apologize as the code was not working due to my mistake. Due to an error in the url I didn't have the prefix ' https://'. Now all works. Thank you all for your help.