command_it 9.1.1
command_it: ^9.1.1 copied to clipboard
command_it is a way to manage your state based on `ValueListenable` and the `Command` design pattern. It is a rebranding of flutter_command.
command_it
#
๐ Complete documentation available at flutter-it.dev Check out the comprehensive docs with detailed guides, examples, and best practices!
๐ Migration Notice (v9.0.0) #
Important: Version 9.0.0 introduces new, clearer API naming. The old API is deprecated and will be removed in v10.0.0.
Quick Migration:
execute()โrun()|isExecutingโisRunning|canExecuteโcanRunRun
dart fix --applyto automatically update most usages.
Command pattern for Flutter - wrap functions as observable objects with automatic state management
Commands replace async methods with reactive alternatives. Wrap your functions, get automatic loading states, error handling, and UI integration. No manual state tracking, no try/catch everywhere.
Call them like functions. React to their state. Simple as that.
Part of flutter_it โ A construction set of independent packages. command_it works standalone or combines with watch_it for reactive UI updates.
Why Commands? #
- ๐ฏ Declarative โ Wrap functions, get observable execution state automatically
- โก Automatic State โ isRunning, value, errors tracked without manual code
- ๐ก๏ธ Smart Error Handling โ Route errors globally/locally with filters
- ๐ Built-in Protection โ Prevents parallel execution automatically
- ๐๏ธ Restrictions โ Disable commands conditionally (auth, network, etc.)
- ๐งช Testable โ Easier to test than traditional async methods
Learn more about the benefits โ
Quick Start #
Installation #
Add to your pubspec.yaml:
dependencies:
command_it: ^9.0.2
listen_it: ^5.3.3 # Required - commands build on ValueListenable
Basic Example #
import 'package:command_it/command_it.dart';
// 1. Create a command that wraps your async function
class CounterManager {
int _counter = 0;
late final incrementCommand = Command.createAsyncNoParam<String>(
() async {
await Future.delayed(Duration(milliseconds: 500));
_counter++;
return _counter.toString();
},
initialValue: '0',
);
}
// 2. Use it in your UI - command is a ValueListenable
class CounterWidget extends StatelessWidget {
final manager = CounterManager();
@override
Widget build(BuildContext context) {
return Column(
children: [
// Shows loading indicator automatically while command runs
ValueListenableBuilder<bool>(
valueListenable: manager.incrementCommand.isRunning,
builder: (context, isRunning, _) {
if (isRunning) return CircularProgressIndicator();
return ValueListenableBuilder<String>(
valueListenable: manager.incrementCommand,
builder: (context, value, _) => Text('Count: $value'),
);
},
),
ElevatedButton(
onPressed: manager.incrementCommand.run,
child: Text('Increment'),
),
],
);
}
}
That's it! The command automatically:
- Prevents parallel execution
- Tracks isRunning state
- Publishes results
- Handles errors
Using CommandBuilder #
Simplify your UI code with the built-in builder widget:
CommandBuilder<void, String>(
command: manager.incrementCommand,
whileRunning: (context, _, __) => CircularProgressIndicator(),
onData: (context, value, _) => Text('Count: $value'),
onError: (context, error, _, __) => Text('Error: $error'),
)
Key Features #
Command Types #
Create commands for any function signature:
- createAsync โ Async with parameter and result
- createAsyncNoParam โ Async without parameter
- createAsyncNoResult โ Async that returns nothing
- createSync โ Sync with parameter and result
- Plus NoParam and NoResult variants for sync commands
Command Properties #
Observe different aspects of execution:
- value โ Last successful result
- isRunning โ Async execution state
- isRunningSync โ Synchronous version for restrictions
- canRun โ Combined restriction and running state
- errors โ Stream of errors
- results โ CommandResult with all data at once
Error Handling #
Declarative error routing with filters:
- Basic Error Handling โ Listen to errors locally
- Global Handler โ App-wide error handling
- Global Errors Stream โ Reactive monitoring of all globally-routed errors
- Error Filters โ Route errors by type or predicate
- Built-in Filters โ GlobalIfNoLocalErrorFilter, PredicatesErrorFilter, etc.
Advanced Features #
- Command Restrictions โ Disable commands conditionally
- CommandBuilder โ Widget for simpler UI code
- Undoable Commands โ Built-in undo/redo support
- Testing โ Patterns for testing commands
Ecosystem Integration #
Built on listen_it โ Commands are ValueListenable objects, so they work with all listen_it operators (map, debounce, where, etc.).
// Register with get_it
di.registerLazySingleton(() => TodoManager());
// Use commands in your managers
class TodoManager {
final loadTodosCommand = Command.createAsyncNoParam<List<Todo>>(
() => api.fetchTodos(),
[],
);
// Debounce search with listen_it operators
final searchCommand = Command.createSync<String, String>((s) => s, '');
TodoManager() {
searchCommand.debounce(Duration(milliseconds: 500)).listen((term, _) {
loadTodosCommand.run();
});
}
}
Want more? Combine with other flutter_it packages:
-
listen_it โ Required dependency. ValueListenable operators and reactive collections.
-
Optional: watch_it โ State management. Watch commands reactively without builders:
watchValue((m) => m.loadCommand). -
Optional: get_it โ Service locator for dependency injection. Access managers with commands from anywhere:
di<TodoManager>().
๐ก flutter_it is a construction set โ command_it works standalone. Add watch_it and get_it when you need reactive UI and dependency injection.
Learn More #
๐ Documentation #
- Getting Started Guide โ Installation, concepts, first command
- Command Basics โ Creating and running commands
- Command Properties โ value, isRunning, canRun, errors, results
- Command Types โ Choosing the right factory function
- Error Handling โ Basic error patterns
- Error Filters โ Advanced error routing
- Command Restrictions โ Conditional execution control
- Command Builders โ Simplifying UI code
- Testing Commands โ Test patterns and examples
- Integration with watch_it โ Reactive UI updates
- Best Practices โ Patterns, anti-patterns, tips
๐ฌ Community & Support #
- Discord โ Get help, share ideas, connect with other developers
- GitHub Issues โ Report bugs, request features
- GitHub Discussions โ Ask questions, share patterns
Contributing #
Contributions are welcome! Please read the contributing guidelines before submitting PRs.
License #
MIT License - see LICENSE file for details.
Part of the flutter_it ecosystem โ Build reactive Flutter apps the easy way. No codegen, no boilerplate, just code.
