Zaid-Ajaj / Fable.Remoting

Type-safe communication layer (RPC-style) for F# featuring Fable and .NET Apps
https://zaid-ajaj.github.io/Fable.Remoting/
MIT License
273 stars 55 forks source link

Maps with record keys deserialization #91

Closed cgravill closed 6 years ago

cgravill commented 6 years ago

I've updated to a recent version of Fable.Remoting and am getting errors on deserialization. I've reduced the issue to maps with records as keys:

type ExampleRecord = {
    prop : int
}

type IServer = {
    recordKeyAPI : unit -> Async<Map<ExampleRecord, int>>
}

let server = {
    recordKeyAPI = fun() -> async { return Map.ofList [({prop = 2}, 3)] }
}

client:

try
    let! exampleCall = server.recordKeyAPI()
    printfn "%O" exampleCall
with ex ->
    console.error ex.Message

Then I get:

Cannot convert ["JString","{\"prop\":2}"] to ["Record",null]

Should that still work if I've got everything configured correctly?

Fable.Remoting.Client (4.5.1) Fable.SimpleJson (2.6)

Zaid-Ajaj commented 6 years ago

Hello there @cgravill, I don't think I have covered such scenario but it I probably should support it, for now as a workaround you can use (Record * int) list until this is fixed

cgravill commented 6 years ago

Thanks for confirming @Zaid-Ajaj

Yep, I'll probably do a workaround like that for now, there are quite a few nested maps on the API but it's straightforward.

Zaid-Ajaj commented 6 years ago

I just added the following test and it seems to work pass fine:

type RecordAsKey = { Key: int; Value : string }

testCase "Deserializing maps with record as key" <| fun test -> 
    [ { Key = 1; Value = "Value" }, 1 ]
    |> Map.ofList 
    |> Json.stringify 
    |> Json.parseNativeAs<Map<RecordAsKey, int>>
    |> Map.toList 
    |> function 
        | [ { Key = 1; Value = "Value" }, 1 ] -> test.pass()
        | otherwise -> test.unexpected otherwise

Do you happen to have a more complex sample that doesn't work? And most importantly, are you using latest dotnet-fable?

cgravill commented 6 years ago

I've only seen it fail in browser, I wasn't able to provoke a failure in the .net itself. Sorry if that wasn't clear - the console error is in Chrome.

dotnet-fable (2.0.9)

Zaid-Ajaj commented 6 years ago

Sorry never mind, I know why it is failing, the JSON generated by the server when serializing maps makes quoted serialized keys, where as SimpleJson doesn't do that when serializing the keys of maps, working on the fix

cgravill commented 6 years ago

Thanks! I started looking at the MapSerializer implementation but wasn't sure how that connects up to the client-side bit.

Zaid-Ajaj commented 6 years ago

The fix is published with v4.5.2, can you please update to check whether the issue persists?

cgravill commented 6 years ago

Thanks, that did it and my app is fully working on Fable 2.x now!

Zaid-Ajaj commented 6 years ago

@cgravill Happy to hear that :smile:

cgravill commented 6 years ago

Incidentally, Fable.Remoting has been very helpful for getting some tools up and running quickly. Many thanks for building it and continuing to develop it with the Fable 2.x changes.