Last updated:
0 purchases
get command
get_command #
This library helps providing feedback to the user while executing a controller function.
It is intended to be used with the Get library.
Let's create an example to showcase the usage:
Create a controller with an async function 'longRunningTask':
import 'package:get/get.dart';
class HomeController extends GetxController {
final count = 0.obs;
@override
void onInit() {
super.onInit();
}
@override
void onReady() {
super.onReady();
}
@override
void onClose() {}
Future<void> longRunningTask() async {
await Future.delayed(Duration(seconds: 1));
count.value++;
}
}
copied to clipboard
Create a simple view
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeView'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(() {
return Text("Current value: ${controller.count}");
}),
ElevatedButton(
child: const Text("Start long running task"),
onPressed: controller.longRunningTask),
],
),
),
);
}
}
copied to clipboard
The problem with this code is that user can tap the button again while the longRunningTask function is currently beening executed.
Let's extend the controller to use a GetCommand:
import 'dart:async';
import 'package:get/get.dart';
import 'package:get_command/get_command.dart';
class HomeController extends GetxController {
final count = 0.obs;
final GetCommand cmdLongRunningTask = GetCommand();
HomeController() {
cmdLongRunningTask.commandFunc = _longRunningTask;
}
@override
void onInit() {
super.onInit();
}
@override
void onReady() {
super.onReady();
}
@override
void onClose() {
cmdLongRunningTask.dispose();
}
FutureOr<void> _longRunningTask() async {
await Future.delayed(Duration(seconds: 1));
count.value++;
}
}
copied to clipboard
What changed:
A new field final GetCommand cmdLongRunningTask = GetCommand(); has been created.
During construction time we set the cmdLongRunningTask.commandFunc = _longRunningTask;. That way we tell the command which function should be executed.
OnClose() calls cmdLongRunningTask.dispose() to release any resources.
Next we update the HomeView to use the Command:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_command_example/app/modules/home/controllers/home_controller.dart';
class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeView'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(() {
return Text("Current value: ${controller.count}");
}),
Obx(() {
return ElevatedButton(
onPressed: controller.cmdLongRunningTask.canBeExecuted
? controller.cmdLongRunningTask.exec
: null,
child: controller.cmdLongRunningTask.executing
? Row(mainAxisSize: MainAxisSize.min, children: [
const Text('Executing'),
const CircularProgressIndicator(),
])
: const Text('Call computation'),
);
}),
],
),
),
);
}
}
copied to clipboard
In that way the button is displayed as disabled and also a litte animation is displayed.
Use
controller.cmdLongRunningTask.exec
copied to clipboard
instead of
controller.cmdLongRunningTask.commandFunc
copied to clipboard
to assign the onPressed event handler.
The exec function calls the commandFunc function.
In the case your controller function throws an exception you have three options to handle that:
Automatically: it will be catched and the errorMessage property has a value of catchedException.toString() and the hasErrorMessage property is set to true. Here an example:
Within the _longRunningTask throw an exception:
FutureOr<void> _longRunningTask() async {
await Future.delayed(Duration(seconds: 1));
throw Exception('Ups :-(');
count.value++;
}
copied to clipboard
since it is not catched, the Command handles it.
Lets extend the view to display the error message:
class HomeView extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('HomeView'),
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(() {
return Text("Current value: ${controller.count}");
}),
Obx(() {
return ElevatedButton(
onPressed: controller.cmdLongRunningTask.canBeExecuted
? controller.cmdLongRunningTask.exec
: null,
child: controller.cmdLongRunningTask.executing
? Row(mainAxisSize: MainAxisSize.min, children: [
const Text('Executing'),
const CircularProgressIndicator(),
])
: const Text('Call computation'),
);
}),
Obx(() {
return Text(
"hasErrorMessage: ${controller.cmdLongRunningTask.hasErrorMessage}");
}),
Obx(() {
return Text(
"errorMessage: ${controller.cmdLongRunningTask.errorMessage}");
}),
],
),
),
);
}
}
copied to clipboard
The _longRunningTask() catches the exception and sets the errorMessage via the setState(...):
FutureOr<void> _longRunningTask() async {
try {
await Future.delayed(Duration(seconds: 1));
throw Exception('Ups :-(');
count.value++;
} on Exception catch (e) {
cmdLongRunningTask.setState(
errorMessage: 'Something went wrong, try again.');
}
}
copied to clipboard
The GetCommand has a optional errorMessageProviderFunc callback function. The function signature is defined as:
typedef ErrorMessageProvider = FutureOr<String> Function(Exception exception);
copied to clipboard
That callback function will be called to get an error message for the given exception.
Let implement such a function within the controller:
I create a dedicated exception:
class OhNoException implements Exception {}
copied to clipboard
that will be thrown within the _longRunningTask()function:
FutureOr<void> _longRunningTask() async {
await Future.delayed(Duration(seconds: 1));
throw OhNoException();
count.value++;
}
copied to clipboard
I create function that have the ErrorMessageProvider signature:
FutureOr<String> _getErrorMessageFor(Exception exception) {
var errorMessage = '';
switch (exception.runtimeType) {
case OhNoException:
errorMessage = 'Oh no - what a mess, try again.';
break;
default:
errorMessage = 'Something went wrong :-(';
}
return errorMessage;
}
copied to clipboard
and assigne that function to the errorMessageProviderFuncproperty of the GetCommand within the constructor:
HomeController() {
cmdLongRunningTask.commandFunc = _longRunningTask;
cmdLongRunningTask.errorMessageProviderFunc = _getErrorMessageFor;
}
copied to clipboard
I Hope that GetCommand class is of any help for you.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.