Flutter "this function has a return type of void and cannot be used"
Asked Answered
H

4

26

I am getting this error: - This expression has a type of 'void' so its value can't be used. Try checking to see if you're using the correct API; there might be a function or call that returns void you didn't expect. Also check type parameters and variables which might also be void.

on line number 134 in this code: -


class toDoList extends StatefulWidget
{
    bool data = false;
    @override
    createState() 
    {
        return new toDoListState();
    }
}

class toDoListState extends State<toDoList>
{
  List<String> tasks = [];
  List<String> completedTasks = [];
  List<String> descriptions = [];
  List<bool> importance = [];
  
    @override
    Widget build(BuildContext context)
    {
        return Scaffold
        (
            body: buildToDoList(),
            floatingActionButton: new FloatingActionButton
            (
                onPressed: addToDoItemScreen, 
                tooltip: 'Add Task',
                child: new Icon(Icons.add),
            ),
        );
    }

    Widget buildToDoList()
    {
        return new ListView.builder
        (
            itemBuilder: (context, index)
            {
                if(index < tasks.length)
                {
                    return row(tasks[index], descriptions[index], index);
                }
            },
        );
    }

    Widget row(String task, String description, int index)
    {                  
        return Dismissible(
        key: UniqueKey(),
        background: Container(color: Colors.red, child: Align(alignment: Alignment.center, child: Text('DELETE', textAlign: TextAlign.center, style: TextStyle(color: Colors.white, fontSize: 18),))),
        direction: DismissDirection.horizontal,
        onDismissed: (direction) {
        setState(() {
          tasks.removeAt(index);
          if(completedTasks.contains(task))
          {
              completedTasks.removeAt(index);
          }
          descriptions.removeAt(index);
          importance.removeAt(index);
        });
          Scaffold.of(context).showSnackBar(SnackBar(content: Text(task+" dismissed")));
        },
        child: CheckboxListTile(
          controlAffinity: ListTileControlAffinity.leading,
          title: Text(task, style: (completedTasks.contains(task)) ? TextStyle(decoration: TextDecoration.lineThrough) : TextStyle(),),
          subtitle: (importance[index]) ? Text('This is important') : Text('No it\'s not'),
          value: completedTasks.contains(task),
          onChanged: (bool value) {
           setState(() {
              if(!completedTasks.contains(task))
              {
                  completedTasks.add(task);
              }
              else
              {
                  completedTasks.remove(task);
              }
           });
          },
        ));
    }
  
  void addToDoItemScreen() {
    int index = tasks.length;
    while (importance.length > tasks.length) {
      importance.removeLast();
    }
    importance.add(false);
    Navigator.of(context).push(new MaterialPageRoute(builder: (context) {
      return StatefulBuilder(builder: (context, setState) { // this is new
        return new Scaffold(
            appBar: new AppBar(title: new Text('Add a new task')),
            body: Form(
              child: Column(
                children: <Widget>[
                  TextField(
                    autofocus: true,
                    onSubmitted: (name) {
                      addToDoItem(name);
                      //Navigator.pop(context); // Close the add todo screen
                    },
                    decoration: new InputDecoration(
                        hintText: 'Enter something to do...',
                        contentPadding: const EdgeInsets.all(20.0),
                        border: OutlineInputBorder()),
                  ),
                  TextField(
                    //autofocus: true,
                    onSubmitted: (val) {
                      addDescription(val, index);
                    },
                    decoration: new InputDecoration(
                        hintText: 'Enter a task decription...',
                        contentPadding: const EdgeInsets.all(20.0),
                        border: OutlineInputBorder()),
                  ),
                  Row(
                    children: <Widget> [
                      Switch(
                      value: importance[index],
                      onChanged: (val) {
                        setState(() {
                        });
                        impTask(index);
                      },
                    ),
                    Text('Important Task', style: TextStyle(fontSize: 18)),
                    ],
                  ),
                  RaisedButton(onPressed: Navigator.pop(context),)
                ],
              ),
            ));
      });
    }));
  }

    void addToDoItem(String task)
    {
        setState(() {
          tasks.add(task);
          descriptions.add("No description");
        });
    }

    void addDescription(String desc, int index)
    {
        setState(() {
          descriptions[index] = desc;
        });
    }

    void impTask(int index)
    {
        setState(() {
          if(importance[index])
          {
            importance[index] = false;
          }
          else 
          {
            importance[index] = true;
          }
        });
    }
}

I don't understand what this is. I am new to flutter. This is my first app. Can someone please help me with this.

Hanrahan answered 3/8, 2020 at 9:3 Comment(1)
Use this instead: RaisedButton(onPressed: () => Navigator.pop(context),)Equipoise
L
61

The issue is with your RaisedButton onPressed.

The onPressed property is a VoidCallback which takes in a Function.

Change it to the code below:

ElevatedButton(onPressed: () => Navigator.pop(context),)
Lytic answered 3/8, 2020 at 9:30 Comment(1)
The "fat arrow" function style seen here is preferable in my opinion.Lighter
T
16

Instead of "onPressed: addToDoItemScreen" to "onPressed: ()=>addToDoItemScreen"

Twitch answered 11/11, 2021 at 3:20 Comment(2)
Please add supporting text, why this works?Acrylyl
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.Acacia
B
3

If you want to call a function, try this:

floatingActionButton: new FloatingActionButton
        (
            onPressed: () { addToDoItemScreen(); }, 
            
        ),

and your function like this:

void addToDoItemScreen() {
   //body
}

And if you want to navigate to different screen, you will have to pass context as a parameter :

floatingActionButton: new FloatingActionButton
    (
        onPressed: () { addToDoItemScreen(context); }, 

    ),

and fuction:

void addToDoItemScreen(BuildContext context)) {
//body
}
Buckish answered 10/8, 2020 at 4:22 Comment(0)
B
0

Inspired in the answer by Void above, I just extract the code into a function, it has the same behavior but I think it is a bit more organized because you can reuse code :)

Answer: https://mcmap.net/q/513339/-flutter-quot-this-function-has-a-return-type-of-void-and-cannot-be-used-quot

  _back(BuildContext context) {
    Navigator.pop(context);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        elevation: 2.0,
        leading: IconButton(
          key: const ValueKey('back'),
          icon: const Icon(Icons.arrow_back),
          onPressed: () => _back(context),
        ),
        title: const Text('Foo Title'),
      ),
      body: _buildBody(context),
    );
  }
Braithwaite answered 12/9, 2021 at 8:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.