Reputation: 105
I want to be able to pass a future as an argument in a class constructor to be used later. Here's the code of the class to help explain...
class Custom extends StatelessWidget {
final String title;
final Future action; //trying to pass a future to be called later
Custom({@required this.title, @required this.action});
@override
Widget build(BuildContext context) {
...
return Column(
children: <Widget> [
Text(title),
RaisedButton(
...
onPressed: () {
action;
}
),
],
),
}
So when I try to build
Custom(title: "print something", action: doSomething())
..what ends up happening is doSomething runs immediately instead of when I press the RaisedButton. If I remove the () at the end of doSomething, I get the error:
The argument type 'Future<dynamic> Function()' can't be assigned to the parameter type 'Future<dynamic>'.
Do I need to do something different in the class constructor? Or if this is not possible, is there a way to achieve this differently?
EDIT:
Based on early answers, I changed my constructor to
final Future Function() action;
Now it builds, but it's still not calling it. I tried creating the future I'm trying to call in both the Custom class and in the class I'm building Custom from, but neither work. Ideally, I'd like to have the Future I'm calling in the class I'm building from. Any suggestions?
EDIT: This is working now. It wasn't working because besides my changes above, I also had to change onPressed: action()
Upvotes: 2
Views: 2511
Reputation: 2614
The error you're seeing is pretty spot on in description. The Future<?> Function()
and Future<?>
are unrelated types. All the functions you write that you wrap with Future<?> functionName() async
are returning an instance of Future
but by themselves have nothing to do with Future
s, so reference to that function can't be used as a parameter that expects Future
type.
Additionally, you need to figure out what to do with generic parameter for the Future
data type. If you leave it as Future
(which is the same as Future<dynamic>
you'll never get compiler errors when forwarding any Future<?>
type there but while you won't get any compile errors you can get into runtime issues if the expected output type of that Future
turns to be something other than the type you're expecting.
If you're only calling Future<void>
method you can simply put Future<void> Function() action;
as your field type. If you're going to be calling different data types but only ever calling the same data type on the same instance of Custom
widget you can make it generic as well, like this:
class Custom<T> extends StatelessWidget {
final String title;
final Future<T> Function() action;
Custom({@required this.title, @required this.action});
//...
}
Upvotes: 0
Reputation: 903
Try changing the declaration to
final Future Function() action;
And use it without the ()
Custom(title: "print something", action: doSomething)
Upvotes: 3