Skip to content

Instantly share code, notes, and snippets.

@nestorsgarzonc
Last active March 3, 2023 20:23
Show Gist options
  • Select an option

  • Save nestorsgarzonc/963b7c81c4cf65b8827e5496481adc08 to your computer and use it in GitHub Desktop.

Select an option

Save nestorsgarzonc/963b7c81c4cf65b8827e5496481adc08 to your computer and use it in GitHub Desktop.
Useful on async operations like a request:
Future<void> getRestaurant() async {
state = state.copyWith(restaurant: StateAsync.loading());
final result = await restaurantRepository.getMenuByRestaurant();
result.fold(
(failure) => state = state.copyWith(restaurant: StateAsync.error(failure)),
(restaurant) => state = state.copyWith(restaurant: StateAsync.success(restaurant)
);
}
class RestaurantState extends Equatable {
const RestaurantState({required this.restaurant});
final StateAsync<RestaurantModel> restaurant;
@override
List<Object?> get props => [restaurant];
RestaurantState copyWith({
StateAsync<RestaurantModel>? restaurant,
}) {
return RestaurantState(
restaurant: restaurant ?? this.restaurant,
);
}
}
class RestaurantTab extends ConsumerWidget {
const RestaurantTab({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final restaurantState = ref.watch(restaurantProvider);
return restaurantState.restaurant.on(
onError: (error) => ErrorWidget(error),
onLoading: () => const ScreenLoadingWidget(),
onInitial: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
ref.read(restaurantProvider.notifier).getRestaurant();
});
return const ScreenLoadingWidget();
},
onData: (restaurant) => RestaurantBody(restaurant: restaurant),
);
}
}
import 'package:equatable/equatable.dart';
import 'package:your-project/failure/failure.dart';
enum States { loading, initial, error, success }
class StateAsync<T> extends Equatable {
const StateAsync(
this._state, [
this._data,
this._error,
]);
factory StateAsync.loading() => const StateAsync(States.loading);
factory StateAsync.initial() => const StateAsync(States.initial);
factory StateAsync.success(T data) => StateAsync(States.success, data);
factory StateAsync.error(Failure error) => StateAsync(States.error, null, error);
final States _state;
final T? _data;
final Failure? _error;
bool get isSucess => _state == States.success;
States get state => _state;
T? get data => _data;
Failure? get error => _error;
W on<W>({
required W Function(T) onData,
required W Function(Failure) onError,
required W Function() onLoading,
required W Function() onInitial,
}) {
switch (_state) {
case States.loading:
return onLoading();
case States.initial:
return onInitial();
case States.success:
return onData(_data as T);
case States.error:
return onError(_error!);
}
}
W onMayNull<W>({
required W Function(T?) onData,
required W Function(Failure) onError,
required W Function() onLoading,
required W Function() onInitial,
}) {
switch (_state) {
case States.loading:
return onLoading();
case States.initial:
return onInitial();
case States.success:
return onData(_data);
case States.error:
return onError(_error!);
}
}
@override
List<Object?> get props => [_state, _data, _error];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment