0

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,
        )
        //...
    }

2 Answers 2

2

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,
)
Sign up to request clarification or add additional context in comments.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
1

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(),
    )
    //...
 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.