Home > Net >  Return type, 'FutureOr<Database>', is a potentially non-nullable type in Flutter
Return type, 'FutureOr<Database>', is a potentially non-nullable type in Flutter

Time:05-11

I am using Flutter and trying to create a database and to use bloc for state management as shown the below code:

 late Database database;
  List<Map> tasks = [];

  Future<void> createDatabase() async {
    database =
        await openDatabase('todo.db', version: 1, onCreate: (database, version) {
      debugPrint('Database created');
      database
          .execute(
              'CREATE TABLE tasks (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, date TEXT, time TEXT, status TEXT, CONSTRAINT task_unique UNIQUE (title, date, time))')
          .then((value) {
        debugPrint('Table created');
      }).catchError((error) {
        debugPrint('Error when creating table ${error.toString()}');
      });
    }, onOpen: (database) {
      getDataFromDatabase(database).then((value) {
        tasks = value;
        emit(AppGetDatabaseState());
      });
      debugPrint('Database opened');
    }).then((value) {
      database = value;
      emit(AppCreateDatabaseState());
    });
  }

The problem is that I am getting an error appears:

The body might complete normally, causing 'null' to be returned, but the return type, 'FutureOr<Database>', is a potentially non-nullable type.

The error appears on this line at the end of the code:

.then((value) {
  database = value;
  emit(AppCreateDatabaseState());
});

CodePudding user response:

Forget about it.. I managed to fix the problem.. I just changed the declaration from

late Database database;

to:

static Database? database;

CodePudding user response:

The whole code seems pretty messy, here's how I've interpreted it:

//Here, we define a constant string, the query that we will execute when creating the database (We want a good looking code)
const String createDatabaseQuery =
    'CREATE TABLE tasks (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, date TEXT, time TEXT, status TEXT, CONSTRAINT task_unique UNIQUE (title, date, time))';

//Probably, when the function will finish you will use the database variable, remember to await the createDatabase function before using it, as it will wait that the function finishes.
Future<void> createDatabase() async {
  //We don't want all those .then! With a great probability, if you use it, you're doing something wrong.
  database = await openDatabase(
    'todo.db',
    version: 1,
    onCreate: (database, version) async {
      try {
        //If the future completes successfully, so there isn't any error
        await database.execute(createDatabaseQuery);
        debugPrint("Database created successfully");
      } catch (error) {
        debugPrint('Error when creating table ${error.toString()}');
      }
    },
    onOpen: (database) async {
      var data = await getDataFromDatabase(database);
      tasks = data;
      emit(AppGetDatabaseState());

      debugPrint('Database opened');
    },
  );
  emit(AppCreateDatabaseState());
}

The code is now way better right? If I understood what you was trying to achieve:

you were trying to do openDatabase(...).then(assignDatabaseVar)

But you've also awaited the future, so dart will see it as

Execute function, execute then block, await then block

But "then" returns void (so null)

And you can't await a null value, only a Future or FutureOr.

Hope I was clear, notice me if it works!

  • Related