# onExit

Each state may define an `onExit` lambda. The `onExit` lambda is called every time the FSM leaves the state regardless of what transition caused the FSM to leave the state. The `onExit` method saves you from having to duplicate common code in for every transition into the state.

```dart

    StateMachine.create((g) => g
          ..initialState<Solid>()
          ..state<Solid>((b) => b
            ..onExit((s, e) => print('We may be melting'))
            ..on<OnMelted, Liquid>()
        );
```

By convention the `onExit` builder should be the first one after the state builder unless there is an `onEnter` builder in which case it should appear after the `onEnter` builder.

It is safe to call `stateMachine.applyEvent` whilst in onExit. The transition will be queued and processed once the current transition has been completed.

## Nested States

When you have a [Nested State](/states/nested-states.md) the onExit action becomes a little more complex. With a Nested State we say that when you enter a state you also enter all ancestor states of that state. In the same way when you leave a state you may leave all of its ancestor states as well as any active child states.

As such we leaving a state we must call onExit for each ancestor upto, but not including, the common ancestor of the old and new state and call onExit for any active child states. (An active state is one that is in the current 'StateOfMind').

As with Class Inheritance we start with the child call its onExit method and the work our way up to the common ancestor.

## Concurrent States

Concurrent States are less complex than Nested States as each concurrent region has an independent set of states so changing state in one region does not affect the state of the other region. Concurrent States can of course be within Nested States and include Nested states so the normal Nested rules apply.

If the state transitions to a state 'above' the concurrent region (closer to the state tree root) then we may need to call the onExit method of all active states in the concurrent regions. If there are two or more active states in the concurrent regions then we do not define the order in which their onExit methods will be called.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://fsm2.onepub.dev/transitions/onexit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
