I think this would be a good issue to open in my learn-halogen repo. Would you mind opening an issue there?
The code below hasn’t been checked for compiler errors, but should give you a good enough idea for how to do it.
- Is this communication unidirectional (e.g. A -> C) or bidirectional (e.g. A <-> C)? If the former, use Query. If the latter, you might want a Bus or something.
While Component A can technically talk to Component C by using either Query or Input, you probably want to use Query.
If using Input, A would update its state, which causes A to re-render itself, thereby passing an Input value into B. B would handle that value via its
Receive action. B could then update its state, which rerenders C, which receives the new Input value via its
Receive action. C then has to know that the input value is a special message from A and thus it should do something.
The downsides of this approach is that A and B’s state has to be updated and view has to be rerendered in order to communicate with C. If that fits your domain situation, then that will work. Otherwise, it’s probably not what you want.
If using Query, neither A nor B’s state needs to change. Rather, clicking on a button in A could trigger a command from A to C through B. Here’s how it would work.
- B would have a Query that allows it to send a Query to C. For example,
Query a = ForwardQuery ChildQuery a. When B needs to handle
ForwardQuery, it simply does
case _ of
ForwardQuery chlidQuery next -> do
void $ H.query childSlot childIndex $ H.tell childQuery
pure (Just next)
- Then A would wrap a C query inside the B’s forwarding query and query B with the forwarding query. For example, A might run the following code inside its
handleAction = case _ of
SendCCommand -> do
void $ H.query slot index $ H.tell $ ForwadQuery ChildQuery