This way you can have a widget update when the value of a certain key updates!
You can just use something like this:
var box = Hive.box('yourBox');
box.watch('yourKey').listen((e) {
setState(() {});
});
This will update your widget when yourKey changes.
setState is not the best practice though, often rebuilds more than what you need.
Could you provide a sample of what you have in mind?
Maybe like
HiveListenable darkMode = HiveListenable(myBox, 'darkMode');
and
ValueListenableBuilder(
valueListenable: darkMode,
builder: (BuildContext context, bool darkMode, Widget child) {
return ListTile(
title: child,
trailing: Switch(
value: darkMode,
onChanged: (bool changed) {
myBox.put('darkMode', changed);
// Or maybe this.darkMode.set(changed);
},
),
);
},
/*
For this example, Text isnt that expensive,
but you can put more expensive widgets here
and they wont constantly rebuild when you want to
change JUST the switch.
*/
child: Text('Dark Mode'),
),
I understand, thanks...
I created the HiveBuilder how do you like it?
Here is a simple example how it works.
I was thinking like this:
class HiveNotifier extends ValueNotifier {
final Box box;
final String key;
HiveNotifier(this.box, this.key) : super(box.get(key)) {
box.watch(key: key).listen((BoxEvent event) {
if (event.value == value) return;
value = event.value;
});
}
@override
get value => box.get(key);
@override
set value(newValue) {
box.put(key, value);
notifyListeners();
}
}
Didn't try to see if it works though.
IMHO, I don’t think you need more than Hive.watch. You can extend its usage for your own specific implementation (Provider, ScopeModel, InheritedWidget, StreamBuilder).
In my case, I am creating a stream from Hive.watch so I can use a StreamBuilder to observe state changes on specific widgets.
Stream<List<String>> watchChanges() {
return Hive.box(boxNameKey)
.watch(key: recentQueriesKey)
.map((event) => fetchQueries());
}
You can create your own ChangeNotifier and observe changes with watch to notifyListeners().
But what I really think is this watch should return the initial value when we listen to a specific key. Currently I have to watch changes and do a separate fetch to receive all values since the very beginning.
IMHO, I don’t think you need more than Hive.watch. You can extend its usage for your own specific implementation (Provider, ScopeModel, InheritedWidget, StreamBuilder).
I agree.
But what I really think is this watch should return the initial value when we listen to a specific key. Currently I have to watch and map to receive all values since the very beginning.
I don't quite undestand what you mean. Do you want to receive all events for a key since the box has been opened? Hive would need to keep them for any key in case you watch that key anytime later.
Sorry, I’ve updated my comment.
I would like that watch had a seedValue for the time I subscribe to it, but only when I am listening to a specific key, like a snapshot.
Otherwise I have to do listen and fetch for the first content not be null, as you do on WatchBoxWidget, this shouldn’t be necessary.
You are right, the reason why I didn't implement that are lazy boxes.
Since lazy boxes don't keep the values in memory, they would need to be fetched for each subscribe call.
I'm not sure how to solve this.
Edit: Maybe using a sendInitialEvent parameter for the watch() method. What do you think?
What about an optional param where we can ask for this initialValue? So it would not be a problem to fetch it again for lazyBox under the hood as in cases like mine we will have to fetch it anyway.
Hahah exactly
Okay let's do that 👍
This has finally been implemented:
ValueListenableBuilder(
valueListenable: Hive.box('settings').listenable(),
builder: (context, box, widget) {
return Center(
child: Switch(
value: box.get('darkMode', defaultValue: false),
onChanged: (val) => box.put('darkMode', val),
),
);
},
)
Thanks @leisim! Hopefully we can get key listeners too because I would rather widgets not rebuild when an irrelevant setting changes.
@MichaelPriebe You can use yourBox.listenable(key: 'someKey')
Amazing!
On Tue, Dec 31, 2019, 1:37 PM Simon Leier notifications@github.com wrote:
@MichaelPriebe https://github.com/MichaelPriebe You can do yourBox.listenable(key:
'someKey')—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/hivedb/hive/issues/20?email_source=notifications&email_token=ABH7BKHL6LVV5ZQJUHJV3OLQ3OGM3A5CNFSM4IMUNYE2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEH4RIEQ#issuecomment-569971730,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABH7BKDFUNNT2E6VDSDXIDDQ3OGM3ANCNFSM4IMUNYEQ
.
Most helpful comment
IMHO, I don’t think you need more than
Hive.watch. You can extend its usage for your own specific implementation (Provider, ScopeModel, InheritedWidget, StreamBuilder).In my case, I am creating a stream from
Hive.watchso I can use aStreamBuilderto observe state changes on specific widgets.You can create your own
ChangeNotifierand observe changes withwatchto notifyListeners().But what I really think is this watch should return the initial value when we listen to a specific key. Currently I have to watch changes and do a separate fetch to receive all values since the very beginning.