如何将外部请求中的JSON对象属性解析为Websharper中的Options?

时间:2015-01-21 23:14:30

标签: json websharper

我希望能够使用模式匹配从外部JSON调用结果的可选属性中安全地提取值。

场景:(将openweathermap api作为随机示例)

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()
  ...

我希望能够通过使用Option根据我的类型正确处理响应对象。正如您所看到的,As<T>转换对于此方案来说还不够好。我找不到合适的解决方案。

这有一个很好的解决方法吗?

注意:我正在使用Websharper 3.0

2 个答案:

答案 0 :(得分:1)

最新的WebSharper 3.0-alpha添加了一个新的OptionalField属性。

您现在可以写

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

并将选项值存储在JS对象上作为缺失或现有字段。记录创建,属性设置器和getter以及RPC调用都将尊重这一点。

答案 1 :(得分:0)

目前无法自动执行此操作。您需要明确转换它:

let optionField<'T> obj name =
    if JS.HasOwnProperty obj name then Some (JS.Get<'T> name obj) else None

type MyType =
  { cod: int option }
  static member FromJson(json: obj) =
    { cod = optionField json "cod" }

然后使用let dat = MyType.FromJson data

但您的想法非常有用,我将其添加为proposal on the websharper github repository