Search code examples
f#elmishsafe-stack

How do I solve encoder problem with the Elmish Debugger?


I've got an application that I've built in SAFE-Stack using websockets, more or less following the approach here: https://github.com/CompositionalIT/safe-sockets

It works fine but the Elmish debugger doesn't like the type of WsSender in this example:


type ConnectionState =
        | DisconnectedFromServer
        | ConnectedToServer of WsSender
        | Connecting

        member this.IsConnected =
            match this with
            | ConnectedToServer _ -> true
            | DisconnectedFromServer | Connecting -> false

    and WsSender = Msg -> Unit

giving the following error message in the Browser Console:

ElmishDebuggerMessage

Can anyone tell me how to go about fixing this issue? (Assuming it's fixable and that I've diagnosed the problem correctly.) Thanks.


Solution

  • you see this error because of Elmish.Debugger using Thoth.Json to serialize your Msg/Model to a JSON format.

    The type WsSender can't be represented in a JSON format because it is a function. So Thoth.Json is asking you to explain how it should encode this type.

    You can do that by creating what is called an extraCoder like that:

    In your case, you will have to create a fake encoder/decoder "just" to make the Debugger happy.

    module CustomEncoders =
    
        let wsSenderEncoder (_ : WsSender) = Encode.string "WsSender function"
    
        let wsSenderDecoder = Decode.fail "Decoding is not supported for WsSender type"
    
        let myExtraCoders =
            Extra.empty
            |> Extra.withCustom wsSenderEncoder wsSenderDecoder 
    
    
        let modelEncoder = Encode.Auto.generateEncoder(extra = myExtraCoders)
        let modelDecoder = Decode.Auto.generateDecoder(extra = myExtraCoders)
    

    In your Program creation, you should replace Program.withDebugger by Program.withDebuggerCoders and give it the encoder and decoder you created.

    Program.withDebuggerCoders CustomEncoders.modelEncoder CustomEncoders.modelDecoder