Types of Callbacks in Flutter

Types of Callbacks in Flutter

·

3 min read

Basically, there are 3 types of callbacks in Dart/Flutter.

  1. Void Callbacks: These callbacks do not return any value. They are used when we want to act without expecting any result in return.

  2. Value Callbacks: These callbacks return a single value. They are used when we want to get a result from a function or an action.

  3. Async Callbacks: These callbacks are used when we want to perform an action that takes some time to complete, such as fetching data from an API or reading data from a file. They return a Future object that can be used to retrieve the result once the action is complete.

Let's look at some examples of them

Void Callbacks:

This is simplest among 3.

We usually encounter it in ElevatedButton, Gestures, InkWell

Here is the simple declaration & calling syntax of it

// Declaration
final VoidCallback callback;

// Usage
callback: => print("Void Callback in action");

Value Callbacks:

Since the intention is to get some value out of callback, that's why accepts a parameter.

We usually encounter it in TextFields, TextForms etc

// Declaration
final ValueChanged<String> onChange;

// Usage
onChange("some value");

Async Callbacks

This one is a bit complex among the 3

Since the intention is to get data/value asynchronously, some new keywords will play an important role such as Future async

// Declaration
Future<Type> asyncCallback() async {
    // Some async operation
   ...
}

// Usage
// To use it we have to use a special `Widget` knowns as `FutureBuilder` which will take this 
FutureBuilder(
      future: asyncCallback(),
      builder: ...
);

Detailed example of Void Callbacks

void main() {
  runApp(VoidCallbackTestWidget());
}

class VoidCallbackTestWidget extends StatefulWidget {
  @override
  _VoidCallbackTestWidget createState() => _VoidCallbackTestWidget();
}

class _VoidCallbackTestWidget extends State<VoidCallbackTestWidget> {
  @override
  Widget build(BuildContext context) {
    return CallableWidget(
      callback: () {
        print("Void Callback in action");
      },
    );
  }
}

class CallableWidget extends StatelessWidget {
  final VoidCallback callback;

  CallableWidget({required this.callback});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: callback,
      child: const Text('Press me'),
    );
  }
}

Details example of Value Callbacks

void main() {
  runApp(ValueCallbackTestWidget());
}

class ValueCallbackTestWidget extends StatefulWidget {
  const ValueCallbackTestWidget({super.key});

  @override
  _ValueCallbackTestWidget createState() => _ValueCallbackTestWidget();
}

class _ValueCallbackTestWidget extends State<ValueCallbackTestWidget> {
  @override
  Widget build(BuildContext context) {
    return CallableWidget(onChange: (changedValue) => print(changedValue));
  }
}

class CallableWidget extends StatelessWidget {
  final ValueChanged<String> onChange;
  const CallableWidget({Key? key, required this.onChange}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return TextField(
      onChanged: (value) {
        onChange(value);
      },
      decoration: const InputDecoration(
        hintText: 'Enter some text...',
      ),
    );
  }
}

Detailed example of Async Callbacks

void main() {
  runApp(AsyncCallbackTestWidget());
}

class AsyncCallbackTestWidget extends StatelessWidget {
  Future<String> fetchData() async {
    // Some async operation
    await Future.delayed(Duration(seconds: 2));
    return 'Data loaded successfully!';
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: fetchData(),
      builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
        if (snapshot.hasData) {
          return Text(snapshot.data!);
        } else if (snapshot.hasError) {
          return Text('Error: ${snapshot.error}');
        } else {
          return const CircularProgressIndicator();
        }
      },
    );
  }
}

Thanks for staying with me.


Hope the different callbacks concepts are now clear.

You can reach out to me via Linked In or https://nasirmomin.web.app