How to read JSON from url using F # JsonProvider
I watched a Channel 9 video on " Why You Should Use F # " and was impressed with how easy it was to pull Wikipedia data. For example, he showed the following code, which lists the various manifestations of Dr Who ...
[<Literal>]
let url = @"https://en.wikipedia.org/wiki/Doctor_Who"
type DoctorWhoData = HtmlProvider<url>
let data = DoctorWhoData.GetSample()
let app = data.Tables.``Changes of appearance``.Rows
As he typed, he had Intellisense on that last line, which made me guess about data detection.
I recently had a requirement to pull some data from the Google Maps API. For example, the following URL retrieves data for the SW1A 1AA postcode in the UK (Buckingham Palace in case anyone is interested!) ...
http://maps.google.com/maps/api/geocode/json?address=sw1a+1aa+uk
Given that the data is just Json, I thought it was equally easy to retrieve information from F #. However, I am stuck trying to get latitude and longitude.
I started with the following ...
type GoogleData = JsonProvider<"http://maps.google.com/maps/api/geocode/json?address=sw1a+1aa+uk">
... but then got stuck trying to fetch the data. Json contains an array with one entry. This contains a geometry
node that contains a location
node that contains two values. In pseudocode, I would expect to do something like this ...
let lat = GoogleData.GetSample().[0].geometry.location.lat
... however it didn't work. I tried this without GetSample () but didn't get much more. Intellisense showed me things that didn't seem to match the Json at all ...
Anyone can advise where I am going wrong? How do I find the data? Moreover, how do I get Intellisense to help me? I was able to do this in C #, but it was a very hit and miss as I had to use a dynamic object so I didn't get Intellisense. Based on what I saw in this video, I was hoping to get Intellisense here.
source to share
The JSON response contains 2 top-level objects, results
and status
.
{
"results" : [
{
"address_components" : [
{
"long_name" : "SW1A 1AA",
"short_name" : "SW1A 1AA",
"types" : [ "postal_code" ]
//snip
],
"status" : "OK"
}
The armor and the long ones are underneath results
, so you need to follow it starting at.GetSample()
let lat = GoogleData.GetSample().Results.[0].Geometry.Location.Lat
To use data other than the example data, use the function Load
:
let honley = GoogleData.Load "http://maps.google.com/maps/api/geocode/json?address=honley+uk"
let honley_latlong = honley.Results.[0].Geometry.Location
//{
// "lat": 53.602267,
// "lng": -1.794173
//}
printfn "%A" honley_latlong
source to share