# Message Search State

A Widget For Controlling A List Of Searched Messages

Find the pub.dev documentation [here](https://pub.dev/documentation/stream_chat_flutter_core/latest/stream_chat_flutter_core/StreamMessageSearchListController-class.html)

### Background

The `StreamMessageSearchListController` is a controller class that allows you to control a list of searched messages.
`StreamMessageSearchListController` is a required parameter of the `StreamMessageSearchListView` widget.
Check the [`StreamMessageSearchListView` documentation](/chat/docs/sdk/flutter/stream-chat-flutter/message-list/stream-message-search-list-view/) to read more about that.

### Basic Example

Building a custom message search feature is a common task. Here is an example of how to use the `StreamMessageSearchListController` to build a simple search list with pagination.

First of all we should create an instance of the `StreamMessageSearchListController` and provide it with the `StreamChatClient` instance.
We can then add a filter to only get the channels that the current user is a part of.
You can also add a list of `SortOption`s and other pagination-related parameters.

```dart
class SearchListPageState extends State<SearchListPage> {
  /// Controller used for loading more data and controlling pagination in
  /// [StreamMessageSearchListController].
  late final messageSearchListController = StreamMessageSearchListController(
    client: StreamChatCore.of(context).client,
    filter: Filter.in_('members', [StreamChat.of(context).currentUser!.id]),
  );
```

Make sure you call `messageSearchListController.doInitialLoad()` to load the initial data and `messageSearchListController.dispose()` when the controller is no longer required.

```dart
@override
void initState() {
  messageSearchListController.doInitialLoad();
  super.initState();
}

@override
void dispose() {
  messageSearchListController.dispose();
  super.dispose();
}
```

The `StreamMessageSearchListController` is basically a [`PagedValueNotifier`](/chat/docs/sdk/flutter/stream-chat-flutter-core/paged-value-listenable-builder/) that notifies you when the list of responses has changed.
You can use a [`PagedValueListenableBuilder`](/chat/docs/sdk/flutter/stream-chat-flutter-core/paged-value-listenable-builder/) to build your UI depending on the latest responses.

```dart
@override
Widget build(BuildContext context) => Scaffold(
      body: Column(
        children: [
          TextField(
            /// This is just a sample implementation of a search field.
            /// In a real-world app you should throttle the search requests.
            /// You can use our library [rate_limiter](https://pub.dev/packages/rate_limiter).
            onChanged: (s) {
              messageSearchListController..searchQuery = s..doInitialLoad();
            },
          ),
          Expanded(
            child: PagedValueListenableBuilder<String, GetMessageResponse>(
              valueListenable: messageSearchListController,
              builder: (context, value, child) {
                return value.when(
                  (responses, nextPageKey, error) => LazyLoadScrollView(
                    onEndOfPage: () async {
                      if (nextPageKey != null) {
                        messageSearchListController.loadMore(nextPageKey);
                      }
                    },
                    child: ListView.builder(
                      /// We're using the responses length when there are no more
                      /// pages to load and there are no errors with pagination.
                      /// In case we need to show a loading indicator or and error
                      /// tile we're increasing the count by 1.
                      itemCount: (nextPageKey != null || error != null)
                          ? responses.length + 1
                          : responses.length,
                      itemBuilder: (BuildContext context, int index) {
                        if (index == responses.length) {
                          if (error != null) {
                            return TextButton(
                              onPressed: () {
                                messageSearchListController.retry();
                              },
                              child: Text(error.message),
                            );
                          }
                          return const CircularProgressIndicator();
                        }

                        final _item = responses[index];
                        return ListTile(
                          title: Text(_item.channel?.name ?? ''),
                          subtitle: Text(_item.message.text ?? ''),
                        );
                      },
                    ),
                  ),
                  loading: () => const Center(
                    child: SizedBox(
                      height: 100,
                      width: 100,
                      child: CircularProgressIndicator(),
                    ),
                  ),
                  error: (e) => Center(
                    child: Text(
                      'Oh no, something went wrong. '
                      'Please check your config. $e',
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
```

In this case we're using the [`LazyLoadScrollView`](/chat/docs/sdk/flutter/stream-chat-flutter-core/lazy-load-scroll-view/) widget to load more data when the user scrolls to the bottom of the list.


---

This page was last updated at 2026-05-22T16:32:00.666Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/flutter/stream-chat-flutter-core/stream-message-search-list-controller/](https://getstream.io/chat/docs/sdk/flutter/stream-chat-flutter-core/stream-message-search-list-controller/).