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 ...enter image description here

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.

+3


source to share


1 answer


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

      

+3


source







All Articles