flutter_stasis_dartz 1.0.0
flutter_stasis_dartz: ^1.0.0 copied to clipboard
dartz Either adapter for flutter_stasis. Bridges Future<Either<F, R>> use cases to StasisViewModel with zero boilerplate.
flutter_stasis_dartz #
dartz adapter for flutter_stasis.
If your use cases return Future<Either<Failure, T>>, this package bridges them to StasisViewModel with zero boilerplate. The core package has no dependency on dartz — this adapter is completely optional.
Installation #
dependencies:
flutter_stasis: ^1.0.0
flutter_stasis_dartz: ^1.0.0
dartz: ^0.10.1
Usage #
Import the adapter and call executeEither exactly like execute:
import 'package:flutter_stasis_dartz/flutter_stasis_dartz.dart';
class ProjectsViewModel
extends StasisViewModel<AppFailure, List<Project>, ProjectsState> {
ProjectsViewModel(this._getProjects)
: super(ProjectsState.initial());
final GetProjectsUseCase _getProjects; // returns Future<Either<AppFailure, List<Project>>>
// Minimal — onError falls back to setError automatically
Future<void> load() => executeEither(
command: _getProjects.call,
onSuccess: setSuccess,
);
// With loading indicator
Future<void> reload() => executeEither(
command: _getProjects.call,
onSuccess: setSuccess,
onLoading: setLoading,
);
// Custom error handling
Future<void> loadSilently() => executeEither(
command: _getProjects.call,
onSuccess: setSuccess,
onError: (f) => emit(ShowSnackBarEvent(f.message)),
);
}
onSuccess is required. onError is optional — defaults to setError. onLoading is optional.
executeEither wraps Future<Either<F, R>> into a Command<F, R> internally and delegates to execute.
With concurrency policy #
executeEither accepts the same CommandPolicy as execute:
Future<void> search(String query) => executeEither(
command: () => _searchUseCase(query),
onSuccess: setSuccess,
onLoading: setLoading,
policy: CommandPolicy.restartable,
);
Converting Either manually #
If you need to convert an Either result outside of a ViewModel, use the extension:
import 'package:flutter_stasis_dartz/flutter_stasis_dartz.dart';
final either = await someUseCase();
final result = either.toCommandResult(); // CommandResult<F, R>
Or wrap any Either-returning function as a Command:
final command = myUseCase.call.asStatekitCommand();
// Command<F, R> — pass to execute(command: command, ...)
How it works #
executeEither is a plain extension method on StasisViewModel. It converts your function into an EitherTaskCommand<F, R> that implements Command<F, R>, then calls the existing execute method. No magic, no hidden state.
extension EitherStasisViewModelX<F, S, T extends StateObject<F, S, T>>
on StasisViewModel<F, S, T> {
Future<CommandResult<F, R>> executeEither<R>({
required Future<Either<F, R>> Function() command,
required FutureOr<void> Function(R result) onSuccess,
FutureOr<void> Function(F failure)? onError, // optional — defaults to setError
FutureOr<void> Function()? onLoading,
CommandPolicy policy = CommandPolicy.parallel,
Object? policyKey,
}) {
return execute<R>(
command: EitherTaskCommand<F, R>(command),
onError: onError,
onSuccess: onSuccess,
onLoading: onLoading,
policy: policy,
policyKey: policyKey,
);
}
}
License #
MIT