ZeroNine
ZeroNine

Reputation: 792

Reading Hivebox value is returning List<dynamic> instead of saved List<Object>

I save a List to an index in a Hive Box.

class Person { 
 String name;
 Person(this.name);
}

List<Person> friends = [];
friends.add(Person('Jerry'));

var accountBox = Hive.openBox('account');
accountBox.put('friends',friends);

//Testing as soon as saved to make sure it's storing correctly.
List<Person> friends = accountBox.get('friends');
assert(friends.length == 1);

so all this works as intended. For some crazy reason when I hot restart the app and try to get the list of friends from Hive, it no longer returns a List<Person>. It returns a List<dynamic>

var accountBox = Hive.openBox('account');
List<Person> friends = accountBox.get('friends');

///ERROR
E/flutter (31497): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled
Exception: type 'List<dynamic>' is not a subtype of type 'List<Person>'
E/flutter (31497): <asynchronous suspension>
etc...

What could be causing this? It's so unusual.

Upvotes: 4

Views: 5257

Answers (3)

mkju
mkju

Reputation: 93

This solved the problem for me

var fooBox = await Hive.openBox<List>("Foo");

var foosList = fooBox.get("foos", defaultValue: []).cast<Foo>();
print(foosList);

This solution from github issue

Upvotes: 8

Lutfi Garzon
Lutfi Garzon

Reputation: 174

There's is an easy way of transforming back your information.

List<T> myList = box.get('key', defaultValue: <T>[]).cast<T>();

As you can see in this example when you get your data you just need to tell the Type for you data to be correctly assigned.

Upvotes: 4

Abion47
Abion47

Reputation: 24671

Hive is predominantly an in-memory database with a file cache. While the app is running, it is likely storing the objects you put into it as-is in memory, but storing the objects in the cache file as serialized binary data. This means that as long as the app is open, you will get your Person list back, but it won't know how to get that data from the cache file. The result is that Hive does its best to deserialize the data and returns it to you as dynamic, but without more information that's as much as it can do.

If you want to keep your data intact after the app closes, you need to tell Hive how to (de)serialize your type. To do that, mark your class appropriately with the Hive annotations.

@HiveType(typeId: 0)
class Person extends HiveObject { 
  @HiveField(0)
  String name;

  Person(this.name);
}

Upvotes: 3

Related Questions