Shmew / Fable.SignalR

A functional type-safe wrapper for SignalR and Fable.
https://shmew.github.io/Fable.SignalR/
MIT License
91 stars 17 forks source link

Q: How do I send a message from a handler function? #24

Closed mastoj closed 3 years ago

mastoj commented 3 years ago

When handling a message how do I get hold of the actual hub so I can send a message? The simple counter example only updates when receiving data, it doesn't ever send anything back from those handlers as I can see.

My first naive approach was this:

    let hub =
      React.useSignalR<Shared.Command, Shared.Event>(fun hub -> 
        hubBuilder.withUrl(sprintf "http://localhost:5000%s" Endpoints.Root)
          .withAutomaticReconnect()
          .configureLogging(LogLevel.Debug)
          .onMessage (handleEvent hub)

When I started implementing handleEvent I realized I just had access to the hub builder, not the actual hub. So what would be the recommended way of getting access to the hub in handleEvent?

mastoj commented 3 years ago

Using elmish I think I would find a more natural way of achieving it, but not sure when it comes to feliz. My working assumption now is that I shouldn't do it, instead I should have the handleEvent to set the state of the component and then have logic in the component to make a call based on said state. Not sure if that is the right approach though.

Shmew commented 3 years ago

You can call onMessage outside of the builder context:

let hub =
    React.useSignalR<Shared.Command, Shared.Event>(fun hub -> 
        hubBuilder.withUrl(sprintf "http://localhost:5000%s" Endpoints.Root)
              .withAutomaticReconnect()
              .configureLogging(LogLevel.Debug)
              .onMessage (handleEvent hub)

React.useEffect((fun () -> hub.onMessage (handleEvent hub)), [||])
mastoj commented 3 years ago

Thanks, I'll try that. I guess the example code is slightly wrong thoug? The first onMessage on row 6 should probably be removed, right?

mastoj commented 3 years ago

Tried it now, but seems like onmessage isn't on the hub that I get from `React.useSignalR

error FSHARP: The type 'IRefValue' does not define the field, constructor or member 'onMessage'. (code 39)

Shmew commented 3 years ago

I'm sorry, I've been dealing with issues from the dotnet client and was mixing up the API between that and Feliz.

Yes your assumption is correct. You'd want to set state and then based on when the value(s) change dispatch a new message to your hub. If that's a behavior you expect to do a lot I'd recommend using the elmish hook to make handling those side effects easier. Honestly though, I'd suspect that a need for this would likely signal a need to refactor the backend logic so you're not sending multiple messages unnecessarily.