UI libraries / Algolia for Flutter / Widgets
Signature
HitsSearcher(
  String applicationID,
  String apiKey,
  String indexName,
  // Optional parameters
  bool disjunctiveFacetingEnabled,
  Duration debounce,
)

HitsSearcher.create(
  String applicationID,
  String apiKey,
  SearchState state,
  // Optional parameters
  bool disjunctiveFacetingEnabled,
  Duration debounce,
)

About this widget

This component is the main entry point for Flutter Helpers: it handles search requests and manages search sessions.

HitsSearcher component has the following behavior:

  • Distinct state changes (including initial state) will trigger a search operation
  • State changes are debounced
  • On a new search request, any previous ongoing search calls will be cancelled

Examples

  1. Create a HitsSearcher
  2. Update search state with query and applyState
  3. Listen to search responses and build the UI
  4. dispose of underlying resources
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class SearchScreen extends StatefulWidget {
  const SearchScreen({super.key});

  @override
  State<SearchScreen> createState() => _SearchScreenState();
}

class _SearchScreenState extends State<SearchScreen> {
  // 1. Create a Hits Searcher
  final hitsSearcher = HitsSearcher(
    applicationID: 'YourApplicationID',
    apiKey: 'YourSearchOnlyApiKey',
    indexName: 'YourIndexName',
  );

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
          // 2. Run your search operations
          title: TextField(
            onChanged: (input) => hitsSearcher.query(input),
            decoration: const InputDecoration(
              hintText: 'Search...',
              prefixIcon: Icon(Icons.search),
              fillColor: Colors.white,
              filled: true,
            ),
          ),
        ),
        // 3.1 Listen to search responses
        body: StreamBuilder<SearchResponse>(
          stream: hitsSearcher.responses,
          builder: (_, snapshot) {
            if (snapshot.hasData) {
              final response = snapshot.data;
              final hits = response?.hits.toList() ?? [];
              // 3.2 Display your search hits
              return ListView.builder(
                itemCount: hits.length,
                itemBuilder: (_, i) => ListTile(title: Text(hits[i]['title'])),
              );
            } else {
              return const Center(child: CircularProgressIndicator());
            }
          },
        ),
      );

  @override
  void dispose() {
    super.dispose();
    // 4. Release underling resources
    hitsSearcher.dispose();
  }
}

Parameters

applicationID
type: String
Required

The ID of your application.

1
2
3
4
5
final hitsSearcher = HitsSearcher(
  applicationID: 'YourApplicationID',
  apiKey: 'YourSearchOnlyApiKey',
  indexName: 'YourIndexName',
);
apiKey
type: String
Required

Your application’s Search-only API key.

1
2
3
4
5
final hitsSearcher = HitsSearcher(
  applicationID: 'YourApplicationID',
  apiKey: 'YourSearchOnlyApiKey',
  indexName: 'YourIndexName',
);
indexName
type: String
Required

The index to search into.

1
2
3
4
5
final hitsSearcher = HitsSearcher(
  applicationID: 'YourApplicationID',
  apiKey: 'YourSearchOnlyApiKey',
  indexName: 'YourIndexName',
);
state
type: SearchState
Required

Initial search state.

1
2
3
4
5
final hitsSearcher = HitsSearcher.create(
  applicationID: 'YourApplicationID',
  apiKey: 'YourSearchOnlyApiKey',
  state: const SearchState(indexName: 'YourIndexName'),
);
disjunctiveFacetingEnabled
type: bool
default: true
Optional

Is disjunctive faceting enabled?

1
2
3
4
5
6
final hitsSearcher = HitsSearcher(
  applicationID: 'YourApplicationID',
  apiKey: 'YourSearchOnlyApiKey',
  indexName: 'YourIndexName',
  disjunctiveFacetingEnabled: true,
);
debounce
type: Duration
default: Duration(milliseconds: 100)
Optional

Search operation debounce duration.

1
2
3
4
5
6
final hitsSearcher = HitsSearcher(
  applicationID: 'YourApplicationID',
  apiKey: 'YourSearchOnlyApiKey',
  indexName: 'YourIndexName',
  debounce: const Duration(milliseconds: 100),
);

Fields

responses
type: Stream<SearchResponse>

Stream of search responses

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
StreamBuilder<SearchResponse>(
  stream: hitsSearcher.responses,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final response = snapshot.data!;
      return Column(
        children: [
          Text('${response.nbHits} hits found'),
          ListView.builder(
            itemCount: response.hits.length,
            itemBuilder: (context, index) {
              final hit = response.hits[index];
              return ListTile(title: Text(hit['name']));
            },
          ),
        ],
      );
    } else {
      return const CircularProgressIndicator();
    }
  },
);
state
type: Stream<SearchState>

Stream of search states

1
2
3
4
5
6
7
8
9
10
11
StreamBuilder<SearchState>(
  stream: searcher.state,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      final query = snapshot.data?.query ?? '';
      return Text('Query: $query');
    } else {
      return const CircularProgressIndicator();
    }
  },
);
eventTracker
type: HitsEventTracker

HitsEventTracker instance responsible for handling and sending user events related to search interactions, such as clicks, conversions, and views. These events help to personalize the user’s search experience by providing insights into user behavior. eventTracker is automatically integrated with the HitsSearcher to track events when users interact with the search results.

1
2
3
4
5
hitsSearcher.eventTracker.clickedObjects(
  indexName: 'your_index_name',
  objectIDs: ['objectID1', 'objectID2'],
  eventName: 'your_event_name',
);

Methods

query

Triggers a search operation with given search query

1
hitsSearcher.query('book');
applyState

Applies a search state configuration and triggers a search operation

1
hitsSearcher.applyState((state) => state.copyWith(query: 'book', page: 0));
snapshot

Gets the latest SearchResponse value submitted by responses stream:

1
final response = hitsSearcher.snapshot();
dispose

Releases all underlying resources

1
hitsSearcher.dispose();
Did you find this page helpful?