How to Solve type ‘Future‘ is not a subtype of type ‘String’ in type cast.
This is a common error, almost every beginner faces this type of errors. You will face this error if you are not fully aware of use of Future. In this tutorial we will learn how to solve ‘Future<String?>’ is not a subtype of type ‘String’ in type cast. Let’s understand future class and how to use it.
What is Future in Flutter?
Future is a class that is used for long running and asynchronous tasks in Dart with async and await keywords. For example if we want to fetch data from a network call without blocking the UI thread, then we will use Future in Flutter. We can say that functionality of this class is equivalent to AsyncTask class in Java. As we use AsyncTask class to perform long running tasks and background tasks in android. Both classes allow the work to run asynchronously.
Let us do a simple example
Let’s assume that we are developing an app that requires products list. This products list has to be fetched from server. And we have to perform a task after fetching products list. Now let us do this without Future.
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Tutorial',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController dateInputController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Future in Flutter'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
fetchProducts();
print('Perform a task after fetching products');
},
child: const Text('Fetch Products'))),
);
}
void fetchProducts() {
Future.delayed(const Duration(seconds: 2)).then((value) => print('Products are fetched'));
}
}
This is the full code of our app. Here we have a button at center of screen with text ‘Fetch Products’. We will press this button to fetch products. On click on this button the method is called fetcheProducts(). This method fetches products from server, but here we just print the message that products are fetched after the delay of 2 seconds.
As we want to fetch products first and then after that want to perform an action. So we call the fetchproducts()method first and then print the next message that ‘Perform a task after fetching products’. Now it should be execute in a way that print the products are fetched message first and then the next message will be print. But if we run this code and press the button. It will print like this.
Output
I/ViewRootImpl@c1d402d[MainActivity](15545): ViewPostIme pointer 0
I/ViewRootImpl@c1d402d[MainActivity](15545): ViewPostIme pointer 1
I/flutter (15545): Perform a task after fetching products
I/flutter (15545): Products are fetched
How to write Future?
A future is exactly like a function in Dart only with a difference of its return type. Its return type is future rather than the void like other functions. If future function returns value then we will add its type as return type of function.
Let’s see how to write a Future function.
Future fetchProducts() async {
await Future.delayed(const Duration(seconds: 2)).then((value) => print('Products are fetched'));
}
Here we have replaced the void with future and add async keyword after function name, and the most important keyword await at the beginning of the line of code which we want to run after a delay of 2 seconds. This is a complete future function with no return type. Because this function is not return any value.
How to call Asynchronous function.
To call a future function you we must need to add async keyword in the calling function. And await keyword before calling that future function. Now we will modify our button’s onPressed method like this.
ElevatedButton(
onPressed: () async {
await fetchProducts();
print('Perform a task after fetching products');
},
child: const Text('Fetch Products'))
Now when we will press the button, it will wait for two seconds and print ‘Products are fetched method’ and after that will print ‘Perform a task after fetching products’ message.
This is our desired output, as we want to fetch products first and then perform the next task.
Return Type of Asynchronous function
Now we will do a simple example with return type of asynchronous function. Let’s return a string from an asynchronous function and print that string in other function.
Future<String> fetchProducts() async {
await Future.delayed(const Duration(seconds: 2));
return 'Products are fetched';
}
This is a function which is returning a string. This function will return string after delay of 2 seconds. Next we will call this function and print its returned string value.
ElevatedButton(
onPressed: () async {
String value = await fetchProducts();
print(value);
print('Perform a task after fetching products');
},
child: const Text('Fetch Products'))
Here you can see that we have modify the onPressed button of elevated button. We just receive the returned value of fetchProducts() function and print that value.
type ‘Future<String?>’ is not a subtype of type ‘String’ in type cast.
Now we will see why developers face this error. When we call an asynchronous function which returns some value. And did not use await keyword to get its return value. Then we face this error.
ElevatedButton(
onPressed: () async {
String value = fetchProducts() as String;
print(value);
print('Perform a task after fetching products');
},
child: const Text('Fetch Products'))
This is the wrong method of calling an asynchronous function. It will cause this error. ‘type ‘Future<String?>’ is not a subtype of type ‘String’ in type cast.’
Conclusion
In this tutorial we have learned that what is future or asynchronous function in flutter and how to use asynchronous function in right way. Hope this will be helpful for you. Thank you for reading.