> For the complete documentation index, see [llms.txt](https://docs.fleaflet.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fleaflet.dev/v7/usage/programmatic-interaction/external-custom-controllers.md).

# External Custom Controllers

For more information about what a `MapController` is, and when it is necessary to set one up in this way, see:

{% content-ref url="/pages/UW2gppPcXFfE46FRhWT6" %}
[Controllers & Cameras](/v7/usage/programmatic-interaction/controllers-and-cameras.md)
{% endcontent-ref %}

***

## Basic Setup

The `FlutterMap.controller` parameter takes an externally intialised `MapController` instance, and attaches it to the map.

```dart
// Within a widget
final mapController = MapController();

@override
Widget build(BuildContext context) =>
    FlutterMap(
        mapController: mapController,
        // ...
    );
```

{% hint style="success" %}
An externally attached controller will be accurately reflected when depending on the `MapController` aspect.
{% endhint %}

{% hint style="warning" %}
It is not safe to assume that the `MapController` is ready to use as soon as an instance has been initialised, for example within `initState`.

See below for more information.
{% endhint %}

## Usage Before Attachment (eg. Within `initState`)

It is not safe to assume that the `MapController` is ready to use as soon as an instance has been initialised, for example within `initState`.

It must first be attached to the `FlutterMap`, which could take up to multiple frames to occur (similar to the way a `ScrollController` is attached to a scrollable view). It helps to avoid errors by thinking of the controller in this way.

{% hint style="warning" %}
Use of the `MapController` before it has been attached to a `FlutterMap` will result in an error being thrown, usually a `LateInitialisationError`.
{% endhint %}

{% hint style="success" %}
It is usually safe to use a controller from within a callback manually initiated by the user without further complications.
{% endhint %}

For example, it is sometimes necessary to use a controller in the `initState()` method (for example to [attach an event listener](/v7/usage/programmatic-interaction/listen-to-events.md)). However, because this method executes before the widget has been built, a controller defined here will not be ready for use.&#x20;

Instead, use the `MapOptions.onMapReady` callback. At this point, it is guaranteed that the controller will have been attached. You could also use this method to complete a `Completer` (and `await` its `Future` elsewhere) if you need to use it elsewhere.

```dart
final mapController = MapController();

@override
void initState() {
    // Cannot use `mapController` safely here
}

@override
Widget build(BuildContext context) {
    return FlutterMap(
        mapController: mapController,
        options: MapOptions(
            onMapReady: () {
                mapController.mapEventStream.listen((evt) {}); // for example
                // Any* other `MapController` dependent methods
            },
        ),
    );
}
```

{% hint style="warning" %}
`MapController` methods that change the position of the map should not be used directly (not as a result of another callback) in `onMapReady` - see [issue #1507](https://github.com/fleaflet/flutter_map/issues/1507). This is an unsupported and usually unnecessary usecase.
{% endhint %}

## Usage Within A State System/Model

{% hint style="danger" %}
Don't define/intialise the a `MapController` within a class or widget that doesn't also contain the `FlutterMap`, such as a state model (eg. `ChangeNotifier`), then try to use it by querying the state in the `FlutterMap.controller` parameter.
{% endhint %}

Instead, some extra care should be taken, which may feel a little backwards at first. The state model should be used AFTER the normal setup.

1. Setup the controller as in [#basic-setup](#basic-setup "mention"), where the `MapController` is defined & initialised directly adjacent to the `FlutterMap`
2. In your state model, create a nullable (and initially uninitialised) `MapController` containing field
3. Follow [#usage-before-attachment-eg.-within-initstate](#usage-before-attachment-eg.-within-initstate "mention") to setup an `onMapReady` callback. Then within this callback, set the state model field.

It may then be beneficial to unset the state model field when the controller is disposed: it should be disposed when the `FlutterMap` is disposed, which should occur just before the widget building the `FlutterMap` is disposed. Therefore, you can override the `dispose` method.

## Animation

Whilst animated movements through `MapController`s aren't built-in, the [community maintained plugin `flutter_map_animations`](https://github.com/TesteurManiak/flutter_map_animations) provides this, and much more!


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.fleaflet.dev/v7/usage/programmatic-interaction/external-custom-controllers.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
