How do I Schedule Effects in Bonsai?

Context: I’m working on migrating our app from Incr_dom, to Bonsai, and one of the differences I noticed is that in incr_dom you can supply an app with an on_startup function that 1) gets called after the first draw, and 2) can schedule further events using schedule_action : Action.t -> unit. I can’t find a similar function in Bonsai. Using edge effects, I’ve been able to recreate 1), but the closest I can get to 2) is providing it with a inject: Action.t -> Ui_effect.t(unit) but I can’t find any way to schedule that effect.

Question: Does anyone know if there is some way to obtain an f : Ui_effect.t(unit) -> unit within a Bonsai computation definition that schedules an effect as a side effect?

The reason I’m looking for a Ui_effect.t(unit) -> unit function, is because I want to be able to hand off a unit -> unit function to an external JavaScript library, and let it schedule an effect as a side effect whenever it wants.

2 Likes

Hi! Sorry for my delayed response!! Thanks for reaching out!

To answer your question:

Question: Does anyone know if there is some way to obtain an f : Ui_effect.t(unit) -> unit within a Bonsai computation definition that schedules an effect as a side effect?

Yes! (with caveats…) Inside of Virtual_dom there exist two functions:

  • Virtual_dom.Vdom.Effect.Expert.handle : #Dom_html.Event Js.t -> unit Effect.t -> unit
  • and also: handle_non_dom_event_exn : unit Effect.t -> unit .

The TLDR on the difference between them is that if you schedule a unit Effect.t that needs access to a dom event to run (I think just Effect.Prevent_default and Effect.Stop_propagation need this from me skimming through the implementation), then you will need to use handle. If the unit Effect.t that you are scheduling does not use either of those effects, then my understanding is that handle_non_dom_event_exn is fine to use. They are also further documented here.

They are under the “Expert” module as it’s more common to schedule effects with the Bonsai.Edge/Bonsai.Apply_action_context.schedule_event/Attr.on_click/… . These functions are useful when performing inter-op with external javascript libraries which sounds like your use case!

Happy to answer any follow-up questions you may have!

1 Like