steveny909
steveny909

Reputation: 105

How do I pass a future to a class constructor in Flutter?

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

Answers (2)

nstosic
nstosic

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 Futures, 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

Farhan Syah
Farhan Syah

Reputation: 903

Try changing the declaration to

final Future Function() action;

And use it without the ()

Custom(title: "print something", action: doSomething)

Upvotes: 3

Related Questions