Future Then: WithHer App – Step 5

We told before that we would come back and discuss the role of the “Future then” method in Flutter. Therefore, here we are.

In this step, we have accomplished many tasks. Certainly, we have done that with a special Future method – then().

Future, then, async, and await

In our App, why do we need the “Future then” method? What is the difference with the keywords – “Future async, and await”?

In this section we will find the answers. In addition, we have also changed the location class in our weather App.

As a result, our weather app is now getting the latitude and longitude from the Geolocator plugin. We’re no longer hard coding the value.

Now our “WithHer” App becomes dynamic. We will discuss that part in the next section.

In this part we will concentrate on Future class.

Why?

Because the Future class plays an important role in our App.

What is Future.then() method?

We have learned that Flutter and Dart is single thread. It does all the work on its main thread. It has no worker thread that runs parallel.

The main thread handles small tasks. When it simultaneously performs heavy task, it may hang, or freeze.

That is why the multi thread concept comes up.

Now, the question is, how Flutter manages this heavy task?

The answer is asynchronous programming. In synchronous programming, everything goes step by step. One after another.

Consequently, if a heavy task falls in the middle, or in the beginning, the whole program halts.

Asynchronous programming solves that issue. Flutter and Dart lets the small tasks to perform before the heavy task. And the heavy task is performed in the background.

Why the Future class is important?

To understand the importance of Future class, let us see a Dart program first where we are downloading a dummy weather data.

The time to download the data takes 8 seconds.

Therefore when we call this function it takes 8 seconds and after that it prints the output.

void main() {
  performAnotherHevyTaskWithThen();
  print('main thread starts....');
  print('main thread ends....');
}

void performAnotherHevyTaskWithThen() {
  Future<String> result = getWeatherDataUsingAnotherAPI();
  result.then((value) {
    print('The content of the file with Future then - $value');
  });
}

Future<String> getWeatherDataUsingAnotherAPI() {
  Future<String> result = Future.delayed(const Duration(seconds: 8), () {
    return 'Downloading File completed after 8 seconds.';
  });
  return result;
}

/**
OUTPUT:
 
main thread starts....
main thread ends....
The content of the file with Future then - Downloading File completed after 8 seconds.

 * 
 * 
 */

In the above code, we have used the “Future then” method. But before that we have told Dart to perform a heavy task that takes 8 seconds to finish.

Future<String> getWeatherDataUsingAnotherAPI() {
  Future<String> result = Future.delayed(const Duration(seconds: 8), () {
    return 'Downloading File completed after 8 seconds.';
  });
  return result;
}

After that, we use the “Future then” method to call the above function.

Watch this part.

void performAnotherHevyTaskWithThen() {
  Future<String> result = getWeatherDataUsingAnotherAPI();
  result.then((value) {
    print('The content of the file with Future then - $value');
  });
}

Lastly, when we call this function in our main thread it executes after 8 seconds. However, Dart allows the small tasks to perform first.

void main() {
  performAnotherHevyTaskWithThen();
  print('main thread starts....');
  print('main thread ends....');
}

/**
OUTPUT::::
 
main thread starts....
main thread ends....
The content of the file with Future then - Downloading File completed after 8 seconds.

 * 
 * 
 */

Before the “Future async and await”, we used the “Future then”.

But the “Future async and await” makes it more simple.

Let us see the code where we use the “Future async and await” instead of “Future then”.

void main() {  
  performAHevyTaskWithAsyncAndAwait();
  print('main thread starts....');
  print('main thread ends....');
}
void performAHevyTaskWithAsyncAndAwait() async {
  String result = await getWeatherDataUsingAnAPI();
  print('The content of the file with Future, async and await - $result');
}

Future<String> getWeatherDataUsingAnAPI() {
  Future<String> result = Future.delayed(const Duration(seconds: 6), () {
    return 'Downloading File completed after 6 seconds.';
  });
  return result;
}
/**
OUTPUT:::
 
main thread starts....
main thread ends....
The content of the file with Future, async and await - Downloading File completed after 6 seconds.

 * 
 * 
 */

The difference between Future then and async, await

As such, both type of Future functions program asynchronously. But there is a major difference.

In “Future then” method, although we return a String value, yet we cannot explicitly declare it.

As a result, we have to declare it as the Future<String> value.

void performAnotherHevyTaskWithThen() {
Future<String> result = getWeatherDataUsingAnotherAPI();
result.then((value) {
...

But, in case of “Future async, await” we confirm that we are getting a String value.

void performAHevyTaskWithAsyncAndAwait() async {
  String result = await getWeatherDataUsingAnAPI();
...

Certainly that makes our task easier than the “Future then” method.

But in some cases, we still prefer to use the “Future then” method. We have done the same thing in our weather App. Take a look at the following image.

The page displays a static Text output that will change as we press the button.

API Flutter first example
API Flutter first example

The Geolocator plugin gets the current latitude and longitude dynamically. After that, based on that value, the user gets the current weather data.

API Flutter second example
API Flutter second example

The Text Button onPressed property updates the data using the “Future then” method.

TextButton(
              onPressed: () {
                location.getCitynameWithGeolocator().then((result) {
                  setState(() {
                    city = result;
                  });
                });
                location.getWeatherDescriptionWithGeolocator().then((result) {
                  setState(() {
                    description = result;
                  });
                });
              },
...
// code is incomplete for brevity
// please clone the project from this branch of GitHub Repository

To sum up, the Future object acts as a promise token. When Flutter finds that some heavy task is waiting it promises the user that in Future you will get it. So please wait.

What is the advantage?

Many.

Because the Future object can return any data type. In the above code it returns String data type. But we can pass and return any data type with the help of the Future object.

What Next?

Books at Leanpub

Books in Apress

My books at Amazon

Courses at Educative

GitHub repository

Technical blog

Twitter

Comments

2 responses to “Future Then: WithHer App – Step 5”

  1. […] After that, in the fifth step, we have discussed Future then, async and await in great detail. […]

  2. […] show date picker in Flutter is an asynchronous function. Therefore, we need to use either the Future then method, or await and […]

Leave a Reply