Search code examples
flutteralgolia

How to update state with each change on text field flutter


I am building a search bar which brings some resuts from algolia. everything is working fine, except that the results listview view doesn't show the new resuts until I close the keyboard. but I need to update automatically with every new letter I write in the text field (while the keyboard is opened), same like auto complete function. what is mimssing here? (note that all of this is inside a buttomsheet)

I also tried to replace the controller listner with onChange (){}, same issue is there. the list view doesn't rebuild untill I close the keyboard.

The Funcion and the listner Code:

class _CategoriesPageState extends State<CategoriesPage> {
String _searchTerm = "";
List<AlgoliaObjectSnapshot> _results = [];
bool _searching = false;
TextEditingController _searchText = TextEditingController(text: "");

_search() async {
setState(() {
  _searching = true;
});

Algolia algolia = const Algolia.init(
  applicationId: 'XP6QXPHMDJ',
  apiKey: '283351eb9d0a111a8fb4f2fdb7b8450a',
);

AlgoliaQuery query = algolia.instance.index('BusinessProfilesCollection');
query = query.query(_searchText.text);

_results = (await query.getObjects()).hits;

setState(() {
  _searching = false;
});
}

@override
void initState() {
_searchText.addListener(() {
  setState(() {
    _search();
  });
});
super.initState();
}

the Text Field Code:

 TextField(
                                  controller: _searchText,
                                  style: GoogleFonts.lato(
                                    fontStyle: FontStyle.normal,
                                    color: Colors.grey[850],
                                    fontSize: 14.sp,
                                  ),
                                  decoration: const InputDecoration(
                                    border: InputBorder.none,
                                    hintText: 'Search ...',
                                    hintStyle:
                                        TextStyle(color: Colors.black),
                                  )),

The Results Widget:

 Container(
                          height: 300.h,
                          child: _searching == true
                              ? Center(
                                  child: Text("Searching, please wait..."),
                                )
                              : _results.length == 0
                                  ? Center(
                                      child: Text("No results found."),
                                    )
                                  : ListView.builder(
                                      itemCount: _results.length,
                                      itemBuilder:
                                          (BuildContext ctx, int index) {return ...}))

Solution

  • A bottom sheet doesnt update state by default. Wrap the content of the bottom sheet with a statefulbuilder

    showModalBottomSheet(
        context: context,
        builder: (context) {
          return StatefulBuilder(
              builder: (BuildContext context, StateSetter setState /*You can rename this!*/) {
            return Container(
              child: TextField(onChanged: (val) {
                setState(() {
                  //This will rebuild the bottom sheet
                });
              }),
            );
          });
    });