Skip to content

Commit a64b8c3

Browse files
committed
fix(search): improve search logic and add query validation
This commit enhances the HeadlineSearchBloc with two key improvements: - Flexible Search: The search filter is updated to use a case-insensitive regex ($regex with $options: 'i'). This allows users to find headlines with partial word matches, rather than requiring the exact title. - Performance Optimization: A guard clause is added to prevent searches for queries shorter than 3 characters. This reduces unnecessary load on the backend and provides a better user experience by avoiding searches on single letters or short fragments.
1 parent 525675e commit a64b8c3

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

lib/headlines-search/bloc/headlines_search_bloc.dart

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:bloc/bloc.dart';
44
import 'package:core/core.dart';
55
import 'package:data_repository/data_repository.dart';
66
import 'package:equatable/equatable.dart';
7+
import 'package:logging/logging.dart';
78
import 'package:stream_transform/stream_transform.dart';
89

910
part 'headlines_search_event.dart';
@@ -26,10 +27,10 @@ EventTransformer<E> debounce<E>(Duration duration) {
2627
class HeadlineSearchBloc
2728
extends Bloc<HeadlineSearchEvent, HeadlineSearchState> {
2829
/// {@macro headline_search_bloc}
29-
HeadlineSearchBloc({
30-
required DataRepository<Headline> headlinesRepository,
31-
}) : _headlinesRepository = headlinesRepository,
32-
super(const HeadlineSearchState()) {
30+
HeadlineSearchBloc({required DataRepository<Headline> headlinesRepository})
31+
: _headlinesRepository = headlinesRepository,
32+
_logger = Logger('HeadlineSearchBloc'),
33+
super(const HeadlineSearchState()) {
3334
on<HeadlineSearchQueryChanged>(
3435
_onHeadlineSearchQueryChanged,
3536
// Apply a debounce transformer to prevent excessive API calls.
@@ -38,6 +39,7 @@ class HeadlineSearchBloc
3839
}
3940

4041
final DataRepository<Headline> _headlinesRepository;
42+
final Logger _logger;
4143

4244
/// Handles the [HeadlineSearchQueryChanged] event.
4345
///
@@ -49,18 +51,32 @@ class HeadlineSearchBloc
4951
) async {
5052
final query = event.query;
5153

52-
// If the query is empty, reset to the initial state.
53-
if (query.isEmpty) {
54-
return emit(const HeadlineSearchState(status: HeadlineSearchStatus.initial));
54+
// If the query is empty or too short, reset to the initial state.
55+
// This prevents heavy, inefficient searches on the backend for 1 or 2
56+
// character queries.
57+
if (query.length < 3) {
58+
return emit(
59+
const HeadlineSearchState(status: HeadlineSearchStatus.initial),
60+
);
5561
}
5662

63+
_logger.info('Searching for headlines with query: "$query"');
64+
5765
// Emit loading state before starting the search.
5866
emit(state.copyWith(status: HeadlineSearchStatus.loading));
5967

6068
try {
61-
// Fetch headlines from the repository with a filter on the title.
69+
// Fetch headlines from the repository using a regex filter for a
70+
// case-insensitive, partial match on the title.
6271
final response = await _headlinesRepository.readAll(
63-
filter: {'title': query},
72+
filter: {
73+
'title': {
74+
// Use regex for partial matching.
75+
r'$regex': query,
76+
// 'i' option for case-insensitivity.
77+
r'$options': 'i',
78+
},
79+
},
6480
pagination: const PaginationOptions(limit: 20),
6581
);
6682

0 commit comments

Comments
 (0)