The Update FunctionΒΆ
In Elm (or Bonsai), the model of an application contains the complete state of the application at any point in time. The model is immutable. The view function displays the complete model in the browser.
This means that any observable change must be caused by a change in the current model. How does that work, given that the model is immutable?
Bonsai maintains mutable references for the application:
- a queue of outstanding messages that should be applied to the current model
- the current model
When commands are emitted, their messages will be queued immediately, and Bonsai will try to apply those messages to the current model as soon as possible. It will call the applications update function with the then current model and the next outstanding message. The update function is responsible for producing the next model state and, optionally, another command.
Updating the model state without issuing any new commands is the common case.
The idiom here is Tuple empty
. An example would
be the update function from our earlier counter example:
update msg model = Tuple empty $
case msg of
Inc ->
model + 1
Dec ->
model - 1
A Dec
message will subtract 1 from the current counter, a Inc
message
will add 1. No additional commands have to be emitted, so it wraps
the new model in Tuple empty
.
In an old version of the animation example, we saw an additional case: a command was issued from the update function. This is accomplished by not returning a plain result, but a real one containing the new model and a (possibly empty) command:
case msg of
SetText str ->
Tuple (pureCommand EndAnimation) (model { text = str } )
Bonsai tries hard to apply as many messages as possible between rendering. Once
it has applied all queued messages (and all messages emitted by the updates),
and has received no additional messages in the mean time, it will schedule
a render via requestAnimationFrame
. If there still are no unapplied messages
in that animation frame, Bonsai will render the model using the view function.