Search code examples
jsonwebsharper

How do I parse JSON object's properties from external request into Options in Websharper?


I want to be able to use pattern matching to safely extract values from optional properties of the result of an external JSON call.

Scenario: (Took openweathermap api as a random example)

type MyType = { cod: int option }
let printCod (x:MyType) = match x.cod with
  | Some cod -> Console.Log(cod)
  | None     -> Console.Log("EMPTY")

let success =
  fun (data, _, _) -> 
    let dat = As<MyType> data
    Console.Log(dat.cod.IsSome)  // prints false
    Console.Log(dat.cod.IsNone)  // prints false
    Console.Log(dat.cod)         // prints correct value
    printCod dat                 // prints undefined

    let dat' = {cod = Some 300}
    Console.Log(dat'.cod.IsSome) // prints true
    Console.Log(dat'.cod.IsNone) // prints false
    printCod dat'                // prints 300
    let dat'' = {cod = None}
    printCod dat''               // prints Empty

let config = 
  JQuery.AjaxConfig
    (Url = "http://api.openweathermap.org/data/2.5/weather?q=London,uk", 
     DataType = (JQuery.DataType.Jsonp :?> _), Success = [| success |])

let AjaxCall() = JQuery.JQuery.Ajax(config)

let Main =
  let _ = AjaxCall()
  ...

I want to be able to handle the response object correctly according to my type by using Option. As you can see the As<T> conversion is not good enough for this scenario. I can't find a proper solution.

Is there a good workaround for this?

NOTE: I'm using Websharper 3.0


Solution

  • A new OptionalField attribute has been added to latest WebSharper 3.0-alpha.

    You can now write

    type MyType = { [<OptionalField>] cod: int option }
    

    and have the option value stored on the JS object as a missing or existing field. Record creation, property setter and getter and RPC calls will all respect this.