Skip to Content
DocumentationBloc AdapterDependent Queries

Dependent Queries (Bloc)

Create queries that depend on other queries by extending QueryCubit and implementing conditional logic.

Basic Dependent Query

class UserPostsQueryCubit extends QueryCubit<List<Post>> { final String userId; UserPostsQueryCubit(this.userId); @override String get key => 'posts:user:$userId'; @override Future<List<Post>> Function() get queryFn => () => api.fetchUserPosts(userId); @override QueryOptions? get options => QueryOptions( enabled: userId.isNotEmpty, ); } class UserPostsScreen extends StatelessWidget { final String userId; const UserPostsScreen({required this.userId}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('User Posts')), body: MultiBlocProvider( providers: [ BlocProvider(create: (context) => UserProfileQueryCubit(userId)), BlocProvider(create: (context) => UserPostsQueryCubit(userId)), ], child: BlocBuilder<UserProfileQueryCubit, QueryState<User>>( builder: (context, userState) { if (userState.isLoading) { return Center(child: CircularProgressIndicator()); } if (!userState.hasData) { return Center(child: Text('User not found')); } final postsCubit = context.read<UserPostsQueryCubit>(); if (userState.hasData && postsCubit.state.isIdle) { postsCubit.refetch(); } return BlocBuilder<UserPostsQueryCubit, QueryState<List<Post>>>( builder: (context, postsState) { if (postsState.isLoading) { return Center(child: Text('Loading posts...')); } if (postsState.hasData) { return PostsList(posts: postsState.data!); } return SizedBox(); }, ); }, ), ), ); } }

Conditional Enabling

Use the enabled option to control when queries execute:

class CategoryProductsQueryCubit extends QueryCubit<List<Product>> { final int? categoryId; CategoryProductsQueryCubit(this.categoryId); @override String get key => 'products:category:$categoryId'; @override Future<List<Product>> Function() get queryFn => () => api.fetchProducts(categoryId!); @override QueryOptions? get options => QueryOptions( enabled: categoryId != null, ); }

Dynamic Dependencies

Create queries with dynamic dependencies based on parent query state:

class UserDashboardScreen extends StatelessWidget { final String userId; const UserDashboardScreen({required this.userId}); @override Widget build(BuildContext context) { return Scaffold( body: MultiBlocProvider( providers: [ BlocProvider(create: (context) => UserProfileQueryCubit(userId)), BlocProvider(create: (context) => UserPostsQueryCubit(userId)), BlocProvider(create: (context) => UserFollowersQueryCubit(userId)), ], child: BlocBuilder<UserProfileQueryCubit, QueryState<User>>( builder: (context, userState) { if (userState.isLoading) { return Center(child: CircularProgressIndicator()); } if (!userState.hasData) { return Center(child: Text('User not found')); } final user = userState.data!; return Column( children: [ UserHeader(user: user), Expanded( child: Row( children: [ Expanded( child: BlocBuilder<UserPostsQueryCubit, QueryState<List<Post>>>( builder: (context, postsState) { return PostsList(posts: postsState.data ?? []); }, ), ), Expanded( child: BlocBuilder<UserFollowersQueryCubit, QueryState<List<User>>>( builder: (context, followersState) { return FollowersList(followers: followersState.data ?? []); }, ), ), ], ), ), ], ); }, ), ), ); } }

Next Steps

Last updated on