Reputation: 343
So I wanted to use Hive for storing notes in a Calendar app but I am stuggling so much with implementing Hive and a ChangeNotifierProvider together . If anyone has an idea on what to do I would like to see it.
Here is my code until now :
@HiveType(typeId: 0)
class EventsBox extends HiveObject {
EventsBox({required this.date, required this.eventsList});
@HiveField(0)
DateTime date;
@HiveField(1)
List<CleanCalendarEvent> eventsList;
}
And here is the FutureProvider that is needed :
final hiveProvider = FutureProvider<HiveDB>((_) => HiveDB.create());
class HiveDB {
var _events;
HiveDB._create() {}
static Future<HiveDB> create() async {
final component = HiveDB._create();
await component._init();
return component;
}
_init() async {
Hive.registerAdapter(EventsBoxAdapter());
this._events = await Hive.openBox<EventsBox>('events');
}
storeEvent(EventsBox eventsMap) {
this._events.put('events', eventsMap);
}
EventsBox getEvents() {
return this._events.get('events');
}
}
I want to use ChangeNotifierProvider and not FutureProvider
Upvotes: 2
Views: 1238
Reputation: 2345
The goal of the provider framework is to inject dependencies into your app without recreating them all the time. In your example, you have your HiveDB
class which is what you want to inject into your app for various other widgets to use it.
IMO, the general approach of "providing" dependencies is:
main()
function)MaterialApp
with the providerProvider<DependencyClass>.of(context)
to access your dependency wherever you need it in your app.Let's see how this applies to your code:
lib/models/event_box.dart
@HiveType(typeId: 0)
class EventsBox extends HiveObject {
@HiveField(0)
DateTime date;
@HiveField(1)
List<CleanCalendarEvent> eventsList;
EventsBox({
required this.date,
required this.eventsList,
});
}
lib/models/hive_db.dart
class HiveDB {
var _events;
HiveDB._create() {}
static Future<HiveDB> create() async {
final component = HiveDB._create();
await component._init();
return component;
}
_init() async {
Hive.registerAdapter(EventsBoxAdapter());
this._events = await Hive.openBox<EventsBox>('events');
}
storeEvent(EventsBox eventsMap) {
this._events.put('events', eventsMap);
}
EventsBox getEvents() {
return this._events.get('events');
}
}
In this case, you want to "provide" (or inject) an instance of
HiveDB
to your app.
HiveDB
instancelib/models/hive_db_provider.dart
class HiveDbProvider extends StatelessWidget {
final HiveDB db;
final Widget child;
const HiveDbProvider({
Key? key,
required this.db,
required this.child,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<HiveDB>.value(
value: db,
child: Consumer<AppCache>(
builder: (context, db, _) {
return child;
},
),
);
}
}
main()
lib/main.dart
void main() async {
final HiveDB db = await HiveDB.create();
runApp(
MyApp(db: db)
);
}
...
lib/main.dart
...
class MyApp extends StatelessWidget {
final HiveDB db;
const PayBuddy({
Key? key,
required this.db,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return HiveDbProvider(
db: db,
child: CacheProvider(
cache: cache,
child: MaterialApp(
...
),
),
);
}
}
Provider
anywhere in your applib/pages/some_screen.dart
import "package:provider/provider.dart";
...
class SomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Access HiveDB instance
final hiveDb = Provider<HiveDB>.of(context);
...
}
}
The sample uses the Provider package which simplifies using provider usage in Flutter.
Upvotes: 3