I am new to flutter and I am running into a bit of trouble. I have a stateful widget class where I generate a list of stateless widgets and pass an async function to the stateless widget. The problem is that the function is being called while being passed (check comments in code). What is the correct way to pass the function and call it from another widget?
Note: I do not want to declare the function in the stateless widget as I want to setState() after the api call (completeTask).
Here is my stateful widget code :
void getData() async {
//...api call to get data
final routesList = List<Widget>.generate(
jsonResponse['id'].length, (i) =>TaskCard(
completeTask: completeTask(int.parse(jsonResponse['id'][i])), //function executed here
)
);
//...
}
completeTask(int id) async{
//... API call
setState(() {
//...
});
}
}
My stateless widget looks like this:
class TaskCard extends StatelessWidget {
TaskCard({Key key, this.id,this.completeTask}) : super(key: key);
Future<void> completeTask;
//...
IconButton(
icon: Icon(Icons.done,color: Colors.green,),
onPressed: () => completeTask,
)
//...
}
CodePudding user response:
I figured it out. Below is the correct code:
void getData() async {
//...api call to get data
final routesList = List<Widget>.generate(
jsonResponse['id'].length, (i) =>TaskCard(
completeTask: () {
setState(() {
completeTask(int.parse(jsonResponse['id'][i]));
},
);
}
)
);
//...
}
This is the other widget
IconButton(
icon: Icon(Icons.done,color: Colors.green,),
onPressed: completeTask,
)
CodePudding user response:
To avoid completeTask
from being called immediately in the Stateful widget, use () => ...
when giving it to the Stateless widget.
So we could have the following in the Stateful widget:
void getData() async {
final routesList = List<Widget>.generate(
jsonResponse['id'].length, (i) => TaskCard(
// so this is the call we should wrap, if we don't do it this way
// we will be calling it directly when the widget is being created
completeTask: () async => completeTask(int.parse(jsonResponse['id'][i])),
)
);
//...
}
Then in the Stateless widget, you need to improve the type of completeTask
. It is Future<void> Function()
and not just Future<void>
class TaskCard extends StatelessWidget {
TaskCard({Key key, this.id, this.completeTask}) : super(key: key);
Future<void> Function() completeTask;
//...
IconButton(
icon: Icon(Icons.done, color: Colors.green),
// remember to call the passed function here, notice the ()
onPressed: () => completeTask(),
)
//...