algolia / algoliasearch-helper-flutter

⚡️ Building block to create instant-search applications with Flutter
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/flutter/
Other
21 stars 14 forks source link

Help filtering by array #126

Closed AfiqMutaz closed 2 months ago

AfiqMutaz commented 4 months ago

The question exists in the docs but the docs lacks implementation specifically for Dart/Flutter. I have an array attribute 'services'. I've already added the attribute to attributesForFaceting. The 'services' attribute contains string values such as 'cleaner', 'electrician', 'plumber' and etc. I'm just not quite sure on how to implement it. Much of the code below is from the Getting Started docs, in their example, a string attribute is used. In its current state of my implementation, the StreamBuilder's snapshot is null. How does the helper know what services are there? Does it read from my index all the available services from the attribute?

  final _filterState = FilterState();

  late final _facetList = _professionalSearcher.buildFacetList(
      filterState: _filterState, attribute: 'services');

  @override
  void initState() {
    _searchTextController.addListener(() => _professionalSearcher.applyState(
        (state) => state.copyWith(query: _searchTextController.text, page: 0)));
    _searchPage.listen((page) {
      if (page.pageKey == 0) {
        _pagingController.refresh();
      }
      _pagingController.appendPage(page.items, page.nextPageKey);
    }).onError((error) => _pagingController.error = error);
    _pagingController.addPageRequestListener((pageKey) => _professionalSearcher
        .applyState((state) => state.copyWith(page: pageKey)));

    _professionalSearcher.connectFilterState(_filterState);
    _filterState.filters.listen((_) => _pagingController.refresh());

    super.initState();
   }
SizedBox(
                  height: 200,
                  child: StreamBuilder<List<SelectableItem<Facet>>>(
                      stream: _facetList.facets,
                      builder: (context, snapshot) {
                        if (!snapshot.hasData) {
                          return const SizedBox.shrink();
                        }
                        final selectableFacets = snapshot.data!;
                        return ListView.builder(
                            padding: const EdgeInsets.all(8),
                            itemCount: selectableFacets.length,
                            itemBuilder: (_, index) {
                              final selectableFacet = selectableFacets[index];
                              return CheckboxListTile(
                                value: selectableFacet.isSelected,
                                title: Text(
                                    "${selectableFacet.item.value} (${selectableFacet.item.count})"),
                                onChanged: (_) {
                                  _facetList.toggle(selectableFacet.item.value);
                                },
                              );
                            });
                      }),
                )
AfiqMutaz commented 2 months ago

I feel silly, after more reading and understand the documentation. You just have to let the HitsSearcher build the the list of filters for you (HitsSearcher.buildFacetList). Set which attribute that you want filtering in your Algolia Dashboard index configuration. The api reference documentation also helped me figure out sorting. https://www.algolia.com/doc/api-reference/widgets/refinement-list/flutter/