Flutter search on input field using StreamBuilder


We are going to see one of the most useful use case that will be used in almost in all the mobile app, which is search and get results from api, For best user experience we generally like to see the autocomplete search result instantly when we start typing in the input using the event stream like keyup, keypress, input etc used in web development world, we are going to see some simple example how to do the same in the Flutter.

What is StreamBuilder in flutter?

In Flutter, a StreamBuilder is a widget that rebuilds whenever a stream provided to it emits a new value. It takes a stream and a builder function as input and automatically rebuilds the widget tree when a new value is emitted from the stream. The builder function receives the latest value emitted by the stream and returns a widget tree based on that value. StreamBuilder is often used to update a part of the UI in response to a stream of data.

Example search screen in flutter using StreamController and StreamBuilder

Here is an example of using a StreamBuilder in Flutter to build a search feature with an input text field and an API call.

First, you will need to create a Stream to hold the search query and bind it to the text field using a TextEditingController.

<code class="">final TextEditingController _searchController = TextEditingController();
final StreamController&lt;String> _searchStream = StreamController&lt;String>();
void initState() {
  _searchController.addListener(() {

Ok then we must prepare to get the data from api, so lets assume you already have an PersonService which handles the api request and response, we are just going to call that Api service from our search page, like below

<code class=""> PersonService personService = PersonService();
  fetchData(query) async {
    return await personService.fetchPersons(query: query);

Next, you can use the StreamBuilder widget to build the search results based on the search query stream.

<code class="">StreamBuilder&lt;Object>(
  initialData: "",
  stream: _searchStream.stream,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      String query = snapshot.data;
      return FutureBuilder(
        future: fetchData(query),
        builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting ||
                        !snapshot.hasData) {
                      return const Center(
                        child: CircularProgressIndicator(),
                 } else if ((snapshot.data! as dynamic).length &lt;= 0) {
                      return const Center(child: Text("No results"));
                 } else {
                      var results = snapshot.data;
                      if (results != null) {
                        return ListView.builder(
                            itemCount: results.length,
                            itemBuilder: (context, index) {
                               Result result = results[index];
                              return ListTile(
                                  title: Text(result.title),
                        return const Text("No results");
    } else {
       return const Center(
              child: CircularProgressIndicator(),

This example uses a FutureBuilder to make an API call and build the search results based on the response. The api.search function returns a Future that resolves to a list of Result objects.

Finally, don’t forget to dispose of the StreamController when the widget is disposed.

<code class="">@override
void dispose() {

I hope this helps! Let me know if you have any questions.

Posted in Flutter and tagged , by .

About Gowri

I am professional web developer with 8+ years experience. PHP, jQuery, WordPress, Angular and Ionic are my key skills in web development. I am working with strong enthusiastic team with spirit. We provide all web related solution like HTML/CSS development, Web graphic design and Logo.