Use of Future Completer in Dart

This blog will look at the programming language Future Completer in Dart. We’ll learn how to execute a demonstration program. Learn how to utilize it in your applications and how to implement it. It applies to the Flutter framework too.

Introduction

You may already be familiar with Future if you work with Dart to create Flutter applications. Future is often used to manage asynchronous tasks. Finding a Future result is a fairly simple procedure.

For instance, getting the result using the await keyword in Dart is possible if we have the Future fetchResult() capability.

Code:

import 'dart:async';

class UserDataFetcher {
  Future<String> fetchUserData() {
    final completer = Completer<String>();

    // Simulating a delayed asynchronous operation
    Future.delayed(Duration(seconds: 5), () {
      final userData = 'John Doe';
      completer.complete(userData); // Completing the Future with data
    });

    return completer.future;
  }
}

void main() async {
  final userDataFetcher = UserDataFetcher();
  final userData = await userDataFetcher.fetchUserData();

  print('Fetched User Data: $userData');
}

Output


Using a Future chain is a second option.

Code:

import 'dart:async';

class UserDataFetcher {
  Future fetchUserData() {
    return Future.delayed(Duration(seconds: 5), () {
      return 'John Doe';
    });
  }
}

void main() async {
  final userDataFetcher = UserDataFetcher();

  userDataFetcher.fetchUserData().then((userData) {
    print('Fetched User Data: $userData');
  }).catchError((error) {
    print('Error fetching user data: $error');
  });

Output


But sometimes, creating a Future using the above mentioned methods takes work. For instance, you need the Future results from a callback function. Let’s examine the following example. There is a method called run in the class MyExecutor. The callback onDone in the class’ constructor is necessary. With a value, the run method will call the onDone way. Obtaining the value passed to the onDone callback is our objective. As a Flutter app developer, tackling such situations efficiently is crucial for building robust and responsive applications.

Code:

import 'dart:async';

class MyExecutor {
  void Function(String time) onDone;

  MyExecutor({
    required this.onDone,
  });

  Future<void> run() async {
    final value = await fetchData(); // Simulating fetching data
    onDone(value); // Call the onDone callback with the fetched value
  }

  Future<String> fetchData() async {
    // Simulating fetching data from an external source
    await Future.delayed(Duration(seconds: 2));
    final DateTime time = DateTime.now();
    final String formattedTime =
        '${time.year}-${time.month}-${time.day} ${time.hour}:${time.minute}:${time.second}';
    return formattedTime;
  }
}

void main() async {
  final MyExecutor myExecutor = MyExecutor(
    onDone: (String time) {
      print('Received value: $time');
      // Handle the value when this callback is invoked
    },
  );

  await myExecutor.run();}

Output


We can’t access the value directly by using await.run() since the run method returns void, which means it returns nothing. Given that everything else is equal, we must obtain the value from the callback.

Completer

To start with, call the constructor of a Completer to create another. It has a type parameter where the bring type back can be identified. Here is an example of a completer that acquires from a string.

Code

final stringCompleter = Completer<String>();

You can create a Completer with a void parameter type if it doesn’t have a return value.

Code

final voidCompleter = Completer<>()

If you don’t specify the type parameter, it will default to dynamic.

final dynamicCompleter = Completer();

If the return value can be null, you can also use a nullable type.

final nullableStringCompleter = Completer<String?>();

Complete Future

You can call the complete technique with a return value to complete the Future. When creating the Completer, the value type should be the same as the type argument. You don’t need to pass any value if the sort border is void. Should it be dynamic, you may return a value of any type. If the sort parameter is void or nullable, you could be allowed to return null.

Code

import 'dart:async';

void main() {
  final completer = Completer();

  // Simulating an asynchronous operation
  Future.delayed(Duration(seconds: 2), () {
    final result = 'Operation completed successfully!';
    completer.complete(result); // Completing the Future with a value
  });

  completer.future.then((value) {
    print('Future completed with value: $value');
  });}

Output


An example of how to end the Future with a string value is shown below.

stringCompleter.complete(‘HURRAH’);

One call to the entire procedure is necessary. If you call the complete method again after What’s in storage is finished, StateError will be thrown.

Complete Future with Error

A future can also throw an error. Using the complete Error method, throwing an error should be possible with Completer.

Code

void completeError(Object error, [StackTrace? stackTrace]);

Here is an example of calling the complete Error technique.

Code

import 'dart:async';

void main() {
  final completer = Completer<String>();

  // Simulating an asynchronous operation with an error
  Future.delayed(Duration(seconds: 2), () {
    try {
      // Simulating an error condition
      throw Exception('An error occurred during the operation');
    } catch (ex, stackTrace) {
      completer.completeError(ex, stackTrace); // Completing the Future with an error
    }
  });

  completer.future.catchError((error, stackTrace) {
    print('Future completed with error: $error');
  });
}

Output


Get Future and Value

If your Completer case has a complete or complete Error method, you can access the future property to retrieve the Future that has finished when that method is invoked. The await keyword can be used to return the value by the Future if you already have one.

Code

final valueFuture = stringCompleter.future;
final value = await valueFuture;

Get Completion Status

To determine the status of the project, go here. You can access the is Completed property by representing things in the Future.

Code:

final isCompleted = stringCompleter.isCompleted;

We are merging the whole code into one screen.

Code

import 'dart:async';

class MyExecutor {
  void Function(String time) onDone;

  MyExecutor({
    required this.onDone,
  });

  Future<void> run() async {
    await Future.delayed(Duration(seconds: 2));
    final DateTime currentTime = DateTime.now();
    final String formattedTime =
        '${currentTime.year}-${currentTime.month}-${currentTime.day} ${currentTime.hour}:${currentTime.minute}:${currentTime.second}';
    onDone(formattedTime);
  }
}

void main() async {
  final timeCompleter = Completer<String>();

  final MyExecutor myExecutor = MyExecutor(onDone: (String time) async {
    try {
      if (time.isNotEmpty) {
        timeCompleter.complete(time);
      } else {
        throw Exception('empty time');
      }
    } catch (ex, stackTrace) {
      timeCompleter.completeError(ex, stackTrace);
    }
  });

  print('Fetching current time...');

  await myExecutor.run();

  final timeValueFuture = timeCompleter.future;
  final timeValue = await timeValueFuture;

  print('Current time: $timeValue');
}


When the application is running, we should see output on the screen similar to the Console Output screen below.

isCompleted: false
isCompleted: true
value: 2023-4-7 14:54:11

Process finished with exit code 0

Flutter Developers from Flutter Agency

Conclusion

I explained the Future Completer in Dart in this post; you can change the code as you see fit. This short introduction to the Future Completer In Dart User Interaction on my part demonstrates how Flutter is used to make it effective.

Completer is a choice that can be used to create a Future in Dart/Flutter. The usage is pretty simple. Call the complete or complete Error strategy if you wish to make a Completer. A completer’s Future can be obtained from the future property. It is possible to determine whether What’s in the Future has been completed using the is Completed property.

This blog will provide enough knowledge to try the Future Completer in Dart of your projects. Please give it a try.

Whether a beginner or an experienced developer, Flutter Agency is a valuable resource to expand your knowledge and improve your proficiency in Dart and Flutter. Happy coding!

Frequently Asked Questions (FAQs)

1. What is Dart with Completer?

Completers represent the concept of completing a task at a later time. Dart allows us to define the entire thing in a completer object rather than transmitting a callback to be triggered together with a future value. Completers are intimately related to Futures because they begin an activity in the Future.

2. How does Flutter’s Completer perform?

Importing the Dart: async core library to use completers would be best.AsyncQuery() interacts with a hypothetical network request represented by getHttpData() in the example. Our procedure will initially return a future but later resolve into string data.

3. Define FutureBuilder.

FutureBuilder is a widget in Flutter that builds itself based on the most current Future snapshot in response to changes in state or dependencies. We can execute asynchronous functions using FutureBuilder and modify our user interface in response to the function’s results.

Book Your Flutter Developer Now

Abhishek Dhanani

Written by Abhishek Dhanani

Abhishek Dhanani, a skilled software developer with 3+ years of experience, masters Dart, JavaScript, TypeScript, and frameworks like Flutter and NodeJS. Proficient in MySQL, Firebase, and cloud platforms AWS and GCP, he delivers innovative digital solutions.

Leave a comment

Your email address will not be published. Required fields are marked *


Discuss Your Project

Connect with Flutter Agency's proficient skilled team for your app development projects across different technologies. We'd love to hear from you! Fill out the form below to discuss your project.

Have Project For Us

Get in Touch

"*" indicates required fields

ready to get started?

Fill out the form below and we will be in touch soon!

"*" indicates required fields