Home > Blockchain >  A value of type 'Future<AppDatabase>' can't be assigned to a variable of type &
A value of type 'Future<AppDatabase>' can't be assigned to a variable of type &

Time:12-09

I am trying to create a persistent interface which forks db calls to floor or another self made web db static store.

Anyway...

The interface part is looking like this: peristent_interface.dart

import 'package:flutter/material.dart';
import 'package:mwork/database/floor/entities/map_location_entity.dart';
import 'package:mwork/database/floor/result/map_location_result.dart';

import 'persistent_stub.dart'
    if(dart.library.io) 'persistent_native.dart'
    if(dart.library.js) 'persistent_web.dart';

abstract class Persistent extends ChangeNotifier {
  static Persistent? _instance;

  static Persistent? get instance{
    _instance ??= getPersistent();
    return _instance;
  }

  Future<List<MapLocationResult?>?> getMapLocations();
  Future<MapLocationResult?> getMapLocation({int id});
  Future<void> insertReplaceMapLocation(MapLocation mapLocation);
  Future<void> insertReplaceMapLocations(List<MapLocation> mapLocations);

} 

All seems nice so far, but the trouble appears when the init() function below returns Future<AppDatabase> not AppDatabase as I want.

persistent_native.dart

import 'package:floor/floor.dart';
import 'package:mwork/database/floor/database/database.dart';
import 'package:mwork/database/floor/entities/map_location_entity.dart';
import 'package:mwork/database/floor/result/map_location_result.dart';
import 'package:mwork/services/persistent/persistent_interface.dart';
import 'package:mwork/common/m_work_config.dart' as m_work_config;

Persistent getPersistent() => PersistentNative();

class PersistentNative extends Persistent {

  final AppDatabase _appDatabase = init();  //<-- Fails here !!

  static Future<AppDatabase> init() async {
    return await $FloorAppDatabase.databaseBuilder(m_work_config.mWorkFloorDb).build();
  }


  @override
  Future<List<MapLocationResult?>?> getMapLocations() async {
    return await _appDatabase.mapLocationDao.getMapLocations();
  }

  @override
  Future<MapLocationResult?> getMapLocation({int id=-1}) async {
    return await _appDatabase.mapLocationDao.getMapLocation(id);
  }

  @override
  Future<void> insertReplaceMapLocation(MapLocation mapLocation) async {
    _appDatabase.mapLocationDao.insertMapLocation(
      mapLocation
    );
  }

  @override
  Future<void> insertReplaceMapLocations(List<MapLocation> mapLocations) async {
    _appDatabase.mapLocationDao.insertMapLocations(
      mapLocations
    );
  }

}

How should I return AppDatabase from init() ?

CodePudding user response:

Maybe you should change the type of the init() function to AppDatabase instead of Future<AppDatabase>? For me it seems that the code is right one and should return AppDatabase.

CodePudding user response:

The init method returns a future, since you wait for it ( and it is a recommended way)

if you would like to return the AppDatabase only, rewrite it as follows::

static AppDatabase init()  {
return $FloorAppDatabase.databaseBuilder(m_work_config.mWorkFloorDb).build().then((AppDatabase db) => db);}

Doing this will have some implications though, this wont be awaited meaning that any call depending on this would return late..

I'd recommend using an await clause to the callee,

for example

static Future<AppDatabase> init() async {
return await $FloorAppDatabase.databaseBuilder(m_work_config.mWorkFloorDb).build();

}

and then calling it as::

final AppDatabase db = await (...........);

or:::

YourClass.init().then((AppDatabase db) { /* anything here*/});
  • Related