Home > Back-end >  Trying to show text from void/string and getting "Closure: (dynamic) => void from Function?
Trying to show text from void/string and getting "Closure: (dynamic) => void from Function?

Time:09-17

So, I am trying to display text from my void in other script file. I am not getting any errors, but I do get some messages instead of the text displayed. (Closure: (dynamic) => void from Function "rannn":. Tasks)

Any one can help me how to fix this issue so it will display the text?

Here is my code

class TaskData extends ChangeNotifier {
  List<Task> _tasks = [
    Task(name: "Task one"),
    Task(name: "Task two"),
    Task(name: "Task three"),
  ];

  UnmodifiableListView<Task> get tasks {
    return UnmodifiableListView(_tasks);
  }

  void rannn(String) async {
    var randomItem = (_tasks.toList()..shuffle()).first.name;
    print(randomItem);
    //notifyListeners();
  }

enter code here

Widget build(BuildContext context) => Container(
        color: Colors.transparent,
        child: Scaffold(
          //backgroundColor: Colors.transparent,
          backgroundColor: Colors.blue,
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                //SizedBox(height: 10),
                Text(
                  "${Provider.of<TaskData>(context).rannn} Tasks",
                ),
                //SizedBox(height: 10),//puts empty box to space things out
                buildTimer(),
                //const SizedBox(height: 10),
                buildButtons(),
              ],
            ),
          ),
        ),
      );

Thank you so much!

CodePudding user response:

You're doing three things wrong.

First: void rannn(String) is a function, if you simply try to print a function you'll get exactly what you're getting now.

Second: void rannn(String) is a void function, so it won't return a Future<String> for you to display. You should return a String from it, like:

Future<String> rann() async {
  return (_tasks.toList()..shuffle()).first.name;
}

Third: You should call the function with () to have access to it's return value:

"${Provider.of<TaskData>(context).rannn()} Tasks",

Problem is, this is a function that returns a Future, so it won't work either.

The solution is to use a FutureBuilder widget, so that you can pass Provider.of<TaskData>(context).rannn() to it's future parameter and wait for the returned future to finally display it in your Text widget

Example:

Future<String> rannn() async {
  await Future.delayed(const Duration(seconds: 2)); // Just so you can see the Future loading
  return (_tasks.toList()..shuffle()).first.name;
}


Widget build(BuildContext context) => Container(
  color: Colors.transparent,
  child: Scaffold(
    backgroundColor: Colors.blue,
    body: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          FutureBuilder(
            future: Provider.of<TaskData>(context).rannn(),
            builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return const Text('Loading...');
              }
              return Text('${snapshot.data}');
            },
          ),
        ],
      ),
    ),
  ),
);
  • Related