Skip to content

Autocomplete widget calls optionsViewBuilder even when optionsBuilder return empty Iterable #108258

Open

Description

@jasontcs

Use case

When using Autocomplete widget, sometime u want the optionsView always visible even the options is empty (for example a header on optionsView or 'No suggestion' optionsView.

Proposal

Autocomplete widget calls optionsViewBuilder even when optionsBuilder return empty Iterable

Activity

  1. added
    in triagePresently being triaged by the triage team
    on Jul 25, 2022
  2. huycozy commented on Jul 25, 2022

    @huycozy
    Member

    Hi @jasontcs, thanks for filing the issue.
    This may be archived by checking options inside optionsViewBuilder for generating a dedicated widget. However, the current options value is only representing matching values in the specified list.
    When the specified list is empty, optionsViewBuilder callback is not invoked.

    Sample code
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      final List<String> _kOptions = <String>[
        'aardvark',
        'bobcat',
        'chameleon',
      ];
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Autocomplete(
                  optionsBuilder: (TextEditingValue textEditingValue) {
                    if (textEditingValue.text == '') {
                      return const Iterable<String>.empty();
                    }
                    return _kOptions.where((String option) {
                      return option.contains(textEditingValue.text.toLowerCase());
                    });
                  },
                  optionsViewBuilder: (BuildContext context, AutocompleteOnSelected<String> onSelected, Iterable<String> options) {
                    print('options: ${options.length}');
                    if (options.isEmpty) return Text('No suggestion');
                    return Align(
                      alignment: Alignment.topLeft,
                      child: Material(
                        elevation: 4.0,
                        child: ConstrainedBox(
                          constraints: const BoxConstraints(maxHeight: 200, maxWidth: 500),
                          child: ListView.builder(
                            padding: EdgeInsets.zero,
                            shrinkWrap: true,
                            itemCount: options.length,
                            itemBuilder: (BuildContext context, int index) {
                              final String option = options.elementAt(index);
                              return InkWell(
                                onTap: () {
                                  onSelected(option);
                                },
                                child: Container(
                                  color: Theme.of(context).focusColor,
                                  padding: const EdgeInsets.all(16.0),
                                  child: Text(option),
                                ),
                              );
                            },
                          ),
                        ),
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    Demo
    Screen.Recording.2022-07-25.at.18.52.34.mp4
    flutter doctor -v
    [✓] Flutter (Channel stable, 3.0.5, on macOS 12.2.1 21D62 darwin-x64, locale en-VN)
        • Flutter version 3.0.5 at /Users/huynq/Documents/GitHub/flutter
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision f1875d570e (9 hours ago), 2022-07-13 11:24:16 -0700
        • Engine revision e85ea0e79c
        • Dart version 2.17.6
        • DevTools version 2.12.2
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
        • Android SDK at /Users/huynq/Library/Android/sdk
        • Platform android-33, build-tools 31.0.0
        • ANDROID_HOME = /Users/huynq/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 13.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • CocoaPods version 1.11.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2021.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    
    [✓] IntelliJ IDEA Community Edition (version 2020.3.3)
        • IntelliJ at /Applications/IntelliJ IDEA CE.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] IntelliJ IDEA Community Edition (version 2022.1.1)
        • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] VS Code (version 1.69.0)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.44.0
    
    [✓] Connected device (3 available)
        • SM T225 (mobile) • R9JT3004VRJ • android-arm64  • Android 11 (API 30)
        • macOS (desktop)  • macos       • darwin-x64     • macOS 12.2.1 21D62 darwin-x64
        • Chrome (web)     • chrome      • web-javascript • Google Chrome 103.0.5060.114
    
    [✓] HTTP Host Availability
        • All required HTTP hosts are available
    
    • No issues found!
    
    [✓] Flutter (Channel master, 3.1.0-0.0.pre.1839, on macOS 12.5 21G72 darwin-x64, locale en-VN)
        • Flutter version 3.1.0-0.0.pre.1839 on channel master at /Users/huynq/Documents/GitHub/flutter_master
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision fa5618082d (3 hours ago), 2022-07-24 20:29:07 -0400
        • Engine revision d9c084560e
        • Dart version 2.19.0 (build 2.19.0-31.0.dev)
        • DevTools version 2.15.0
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
        • Android SDK at /Users/huynq/Library/Android/sdk
        • Platform android-33, build-tools 31.0.0
        • ANDROID_HOME = /Users/huynq/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
        • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 13.3)
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 13E113
        • CocoaPods version 1.11.3
    
    [✓] Chrome - develop for the web
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2021.2)
        • Android Studio at /Applications/Android Studio.app/Contents
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
        • Java version OpenJDK Runtime Environment (build 11.0.12+0-b1504.28-7817840)
    
    [✓] IntelliJ IDEA Community Edition (version 2020.3.3)
        • IntelliJ at /Applications/IntelliJ IDEA CE.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] IntelliJ IDEA Community Edition (version 2022.1.1)
        • IntelliJ at /Users/huynq/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/221.5591.52/IntelliJ IDEA CE.app
        • Flutter plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/9212-flutter
        • Dart plugin can be installed from:
          🔨 https://plugins.jetbrains.com/plugin/6351-dart
    
    [✓] VS Code (version 1.69.2)
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.44.0
    
    [✓] Connected device (4 available)
        • SM T225 (mobile)   • R9JT3004VRJ                          • android-arm64  • Android 11 (API 30)
        • iPhone 13 (mobile) • 2526BC1A-435D-4B08-B99C-44B928F2517B • ios            • com.apple.CoreSimulator.SimRuntime.iOS-15-4 (simulator)
        • macOS (desktop)    • macos                                • darwin-x64     • macOS 12.5 21G72 darwin-x64
        • Chrome (web)       • chrome                               • web-javascript • Google Chrome 103.0.5060.134
    
    [✓] HTTP Host Availability
        • All required HTTP hosts are available
    
    • No issues found!
    

    Labeling this issue as a proposal for further discussion/opinion.

  3. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    p: material_uimaterial_ui package in flutter/packages
    c: proposalA detailed proposal for a change to Flutter
    and removed
    in triagePresently being triaged by the triage team
    on Jul 25, 2022
  4. vHanda commented on Jan 9, 2023

    @vHanda

    Hi.

    I'd like to show a special screen to indicate that no results were found. Since the optionsViewBuilder is not called when the returned options are empty. It's difficult to show it.

    For now, I'm hacked around it by adding a special empty item.

    image

    This isn't the most elegant solution. A proper one would be wonderful.

  5. flutter-triage-bot commented on Mar 23, 2024

    @flutter-triage-bot

    This issue is missing a priority label. Please set a priority label when adding the triaged-design label.

  6. added
    P2Important issues not at the top of the work list
    triaged-designTriaged by Design Languages team
    on Mar 28, 2024
  7. HansMuller commented on Mar 28, 2024

    @HansMuller
    Contributor

    @LongCatIsLooong - is this still an issue?

  8. LongCatIsLooong commented on Mar 28, 2024

    @LongCatIsLooong
    Contributor

    I think this is a feature request for a builder that builds the entire options view instead of one that builds each option individually? I'm not aware of any existing APIs that allow you to achieve that. /cc @justinmc

  9. victorsanni commented on Apr 22, 2024

    @victorsanni
    Contributor

    One way I was able to fix it was by allowing the options view to be shown even when the options iterable is empty.

    Before

    autocompletewithoutextra-ezgif com-video-to-gif-converter

    After

    autocompletewithempty-ezgif com-video-to-gif-converter

    If all options are shown when `textEditingValue.text` is empty

    ezgif com-video-to-gif-converter (1)

    code sample
    
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key, required this.title}) : super(key: key);
    
      final String title;
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      final List<String> _kOptions = <String>[
        'aardvark',
        'bobcat',
        'chameleon',
      ];
      TabBar? tabBar;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Autocomplete(
                  optionsBuilder: (TextEditingValue textEditingValue) {
                    if (textEditingValue.text == '') {
                      return const Iterable<String>.empty();
                    }
                    final Iterable<String> options =
                        _kOptions.where((String option) {
                      return option.contains(textEditingValue.text.toLowerCase());
                    });
    
                    return options;
                  },
                  optionsViewBuilder: (BuildContext context,
                      AutocompleteOnSelected<String> onSelected,
                      Iterable<String> options) {
                    if (options.isEmpty) {
                      return const Text('No suggestion');
                    }
                    return Align(
                      alignment: Alignment.topLeft,
                      child: Material(
                        elevation: 4.0,
                        child: ConstrainedBox(
                          constraints:
                              const BoxConstraints(maxHeight: 200, maxWidth: 500),
                          child: ListView.builder(
                            padding: EdgeInsets.zero,
                            shrinkWrap: true,
                            itemCount: options.length,
                            itemBuilder: (BuildContext context, int index) {
                              final String option = options.elementAt(index);
                              return InkWell(
                                onTap: () {
                                  onSelected(option);
                                },
                                child: Container(
                                  color: Theme.of(context).focusColor,
                                  padding: const EdgeInsets.all(16.0),
                                  child: Text(option),
                                ),
                              );
                            },
                          ),
                        ),
                      ),
                    );
                  },
                ),
              ],
            ),
          ),
        );
      }
    }
    
    

    @jasontcs is this the desired behavior?

  10. victorsanni commented on Jul 26, 2024

    @victorsanni
    Contributor

    I have a partial patch here: #147900. Feel free to take inspiration from the review comments etc.

  11. VerzCar commented on Aug 6, 2024

    @VerzCar

    Any updates on this? As it seems a common behaviour this widget should offer some API to solve this issue.

  12. victorsanni commented on Aug 6, 2024

    @victorsanni
    Contributor

    Any updates on this? As it seems a common behaviour this widget should offer some API to solve this issue.

    Thanks for reaching out. I closed #148995 because it had been on the flutter team's review queue for a while, and it was blocked on #150776 anyways. Once #150776 is merged, it should be easier to solve this issue.

    In the meantime, please feel free to explore the changes and review comments in #148995 for more context. This is a difficult issue to solve well, and more folks to help out on it would be deeply appreciated.

  13. marc-wilson commented on Aug 15, 2024

    @marc-wilson

    Just hit this as well. I would expect optionsViewBuilder to fire in the event of an empty dataset.

  14. jchannon commented on Jul 29, 2025

    @jchannon

    Also just hit this but optionsViewBuilder doesn't fire at all if optionsBuilder returns an empty list so I can't inspect and show a "No results found" widget.

    I have to add the below in optionsBuilder to get optionsViewBuilder to work so I can show a widget.

    I'm new to Flutter so just lost a few hours to this 😢

    if(options.isEmpty) {
                    return <String>["No results found"];
                  }
    
  15. victorsanni commented on May 8, 2026

    @victorsanni
    Contributor
  16. added
    packageflutter/packages repository. See also p: labels.
    and removed
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: proposalA detailed proposal for a change to Flutterp: material_uimaterial_ui package in flutter/packagespackageflutter/packages repository. See also p: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages teamworkaround availableThere is a workaround available to overcome the issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions