I’ve make a singleton class as Hive
initialization. But when I call the getter inside that class, it never return a value and returning an error instead. I’ve tried with ?
mark, it return Null check operator used on a null value
when I call it wit !
marks. Also tried with late
and it give error LateInitialization
.
class Takok {
static final Takok _t = Takok._internal();
factory Takok() => _t;
Takok._internal();
Box<Transaksi>? _boxTransaksi;
Box<InappProses>? _boxInappProses;
Future<Takok> akses() async {
final takok = Takok._internal();
final direktori = await getApplicationDocumentsDirectory();
await Hive.initFlutter(direktori.path);
await takok.init();
return takok;
}
Future<void> init() async {
Hive.registerAdapter(TransaksiAdapter());
Hive.registerAdapter(InappProsesAdapter());
this._boxTransaksi = await Hive.openBox<Transaksi>('transaksi');
this._boxInappProses = await Hive.openBox<InappProses>('inappproses');
}
Box<Transaksi> get boxTransaksi => _boxTransaksi!;
Box<InappProses> get boxInappProses => _boxInappProses!;
}
When I try to check if the box is open on main()
function, it returns true.
void main() async {
await Takok().akses().then((value) {
[value.boxTransaksi,value.boxInappProses].forEach((element) {
if (element.isOpen) print('$element is open');
});
print('done checking');
});
}
Anyone can help or explain to me how to fix this? I want to use inside a provider (riverpod exactly), like :
final providerTakok = Provider<Takok>((ref) => Takok());
final providerTakokHelper = ChangeNotifierProvider<TakokHelper>((ref) {
final db = ref.read(providerTakok);
final inapp = db.boxInappProses; // <-- this line which give the error
return TakokHelper(db, inapp);
});
Then I consume above provider to another provider
final providerSplashskrin = Provider((ref) {
Future.delayed(
const Duration(seconds: 3),
() async {
try {
final takokHelper = ref.watch(providerTakokHelper);
print('objection'); // this line was printed if placed above takokHelper
// ...
} catch (e) {
print('error: $e')
}
},
);
});
And this is TakokHelper.dart
class TakokHelper extends ChangeNotifier {
final Takok takok;
final Box<InappProses> box;
TakokHelper(this.takok, this.box)
// ...
}
Thank you.
2
Answers
After a last couple of days struggling and confused by my self, I finally fix the issue. The Hive initialization and opening Hive box must be in the same function. So in Takok.dart I merge the
akses()
andinit()
Takok.dart
The whole point is that you cannot use
ref.watch
in callbacks. Try usingref.read
orref.listen
.As for the first part of your question, you can use
ProviderContainer
to load all your dependencies in it and pass such a container toUncontrolledProviderScope
. Or override your provider after the value is loaded like this: