danielcenoz
danielcenoz

Reputation: 65

Flutter 'The setter 'task= ' was called on null

everyone! I'm learning Flutter / Dart and keep having issues with instantiation and initialization. Currently I'm writing a reorderable list but for some reason, I can't populate the list because my instance has some issue... (I think the issue is at these lines below)

List<String> tasks = [];
MyTask t;
tasks = [ t.task = 'Buy ice cream', t.task = 'Learn Flutter', t.task = 'Read books' ];)

Can you check it and give me a clue? Thanks in advance. Any tip to seek docs is welcome! Exception:

════════ Exception caught by widgets library ═══════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building _BodyBuilder:
The setter 'task=' was called on null.
Receiver: null
Tried calling: task="Buy ice cream"

Relevant code:

import 'package:flutter/material.dart';
import './bottomNavigationBar.dart';
import './ViewFeed.dart';
import './ViewNewTodo.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      //home: MyScaffold(),
      initialRoute: '/',
      routes: {
        '/':(context) => MyFeed(),
        '/toDo':(context) => MyScaffold(),
        '/newToDo':(context) => MyNewTodo(),
      },
    );
  }
}

class MyScaffold extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My ToDoS'),
      ),
      body: MyReorderableTaskList(),
      floatingActionButton: MyFloatingActionButtonNewTodo() ,
      bottomNavigationBar: MyBottomNavigationBar(),
    );
  }
}

//Reorderable list elements
//FloatingActionButton
class MyFloatingActionButtonNewTodo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      child: Icon(Icons.add),
      tooltip: 'Idea',
      onPressed: ()=>{ Navigator.pushNamed(context, '/newToDo') },
    );
  }
}

class MyTask{
  String task;
  MyTask(this.task);
}
//ReorderableListView  implementation

class MyReorderableTaskList extends StatefulWidget {
  @override
  _MyReorderableTaskListState createState() => _MyReorderableTaskListState();
}

class _MyReorderableTaskListState extends State<MyReorderableTaskList> {
  List<String> tasks = [];
  MyTask t;

  void initState(){
    tasks = [ t.task = 'Buy ice cream', t.task = 'Learn Flutter', t.task = 'Read books' ];
    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return ReorderableListView(
        onReorder: _onReorder,
        children: List.generate(
            tasks.length,
              (index){ return MyListView(index, Key('$index'), tasks ); }
              ),
          );
  }
  void _onReorder(int oldIndex, int newIndex){
    setState(() {
        if(newIndex > oldIndex) { newIndex -= 1; }
        final String item = tasks.removeAt(oldIndex);
        tasks.insert(newIndex, item);
    });
  }
}

class MyListView extends StatefulWidget {
  final int index;
  final Key key;
  final List<String> listTasks;
  MyListView(this.index, this.key, this.listTasks);
  @override
  _MyListViewState createState() => _MyListViewState();
}

class _MyListViewState extends State<MyListView> {
  @override
  Widget build(BuildContext context) {
    return Card(
         margin: EdgeInsets.all(6),
          child: InkWell(
            splashColor: Colors.blue,
            onTap: ()=>{ MaterialState.focused },
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                ListTile(
                  title: Text('Tarea: ${widget.listTasks[widget.index]} | ${widget.index}',),
                ),
              ],
            ),
          ),
        );
      }
}



Upvotes: 0

Views: 1810

Answers (1)

Shahmil
Shahmil

Reputation: 341

MyTask t; is null. t isn't actually anything yet. You must create a new object MyTask() and assign it to t

Change it to

MyTask t = new MyTask("");

Edit: More thorough explanation

You can't just declare MyTask t; and then try to use t, because you have not yet said what t is. That's like declaring int a; and then trying to do print(a + 5). You can't do that, because you have not yet assigned a value to a. Similarly, MyTask t; means you have created a variable named t of type MyTask. In other words, you have declared a variable t. But you must still initialize it, in other words, assign t a value of type MyTask, otherwise the value of t will be null.

So to summarize,

MyTask t;
t.task = "Hello";

will not work, because it's like doing

int a;
int b = a + 5;

You can't add 5 to a, because although you have declared the variable a, you have not yet initialized it, so it does not yet have a value.

Likewise, you can't access the .task property of t, because you haven't said what t is. t is just null.

So you must initialize t by instantiating a new MyTask object-

MyTask t = new MyTask("");

The "" is required inside the parentheses because your MyTask class constructor requires a parameter.

class MyTask{
  String task;
  MyTask(this.task); // Parameter required to assign to the String task
}

This might help you.

Upvotes: 2

Related Questions