How to solve "The property 'length' can't be unconditionally accessed because the receiver can be 'null'"

Viewed 3054

I have added conditions too for the reciever to not be null but the error persists. These are 2 errors which I am unable to solve.Please help! I am making "Notes" application where I am storing values in sqflite db.

        body: FutureBuilder(
          future: getNotes(),
          builder: (context, noteData) {
            switch (noteData.connectionState) {
              case ConnectionState.waiting:
                {
                  return Center(child: CircularProgressIndicator());
                }
              case ConnectionState.done:
                {
                  if (noteData.data == null) {
                    return Center(
                      child: Text("You don't have any notes yet, create one!"),
                    );
                  } else {
                    return Padding(
                      padding: EdgeInsets.all(8.0),
                      child: ListView.builder(
                         itemCount: noteData.data.length,   //Error
                        itemBuilder: (context, index) {
                          String title = noteData.data[index]['title'];// Error-The method '[]' can't be 
                                                                  //unconditionally invoked because the receiver //can be 'null'.
                          String body = noteData.data[index]['body'];
                          String creation_date =
                              noteData.data[index]['creation_date'];
                          int id = noteData.data[index]['id'];

             
3 Answers

Had the same error, mine was solved when I put "AsyncSnapshot" before noteData

That's related to Dart null-safety. One way to resolve this is using the bang operator since you are sure that noteData.data is never null (you are checking that before using), e.g.:

noteData.data!.length, noteData.data![index]['title'] and so on.

This solution could seem cumbersome, so I would recommend creating a local variable before using noteData.data:

...
} else {
  final data = noteData.data; // noteData.data! could be needed here, not sure

  return Padding(
    padding: EdgeInsets.all(8.0),
      child: ListView.builder(
        itemCount: data.length,
        ...
      ),
    ),
  );
}

  Future<dynamic> getNotes() async {
    final db = await database;
    var res = await db!.query("notes");
    if (res.length == 0) {
      return null;
    } else {
      var resultMap = res.toList();
      return resultMap.isNotEmpty ? resultMap : null;
    }
  }

and this is my Note class

class NoteModel {
  final int? id;
  final String? title;
  final String? body;
  final DateTime? creation_date;

  NoteModel({this.id, this.title, this.body, this.creation_date});

  Map<String, dynamic> toMap() {
    return ({
      "id": id,
      "title": title,
      "body": body,
      "creation_date": creation_date
    });
  }
}
Related