isar / isar/hive

When get List<T> Hive V4 throws 'Type Mismatch' error

Open
#1,302 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
4.4k
Forks
449
PR merge metrics
No merged PRs in 30d

Description

I have tried to make module from Hive with Generic models. Created 'CacheModel' mixin like this:

```
mixin CacheModel {
String get id;

CacheModel fromDynamicJson(dynamic json);
Map toJson();
}
```

And a manager to registerAdapters like this:

```
final class HiveCacheManager extends CacheManager {
HiveCacheManager({super.path});

@override
Future init({required List cacheModels}) async {
final documentPath =
path ?? (await getApplicationDocumentsDirectory()).path;
Hive.defaultDirectory = documentPath;

for (final cacheModel in cacheModels) {
Hive.registerAdapter(
'${cacheModel.runtimeType}', cacheModel.fromDynamicJson);
}
}

@override
void remove() {
Hive.deleteAllBoxesFromDisk();
}
}

```
CacheManager is an abstract class and have a CacheOperation abstract class like this:

```
abstract class CacheOperation {
void add(T item);
void addAll(List items);
void remove(String id);

void clear();
List getAll();
T? get(String id);
T? getFirst();
}
```

I also have a HiveCacheOperation which extends CacheOperation of T Type like this:

```
final class HiveCacheOperation extends CacheOperation {
HiveCacheOperation() {
_box = Hive.box(name: T.toString());
}

late final Box _box;
@override
void add(T item) {
_box.put(item.id, item);
}

@override
void addAll(List items) {

_box.putAll(Map.fromIterable(
items,
key: (element) => (element as T).id,
value: (element) => (element as T),
));

}

@override
void clear() {
_box.clear();
}

@override
T? get(String id) {
return _box.get(id);
}

@override
T? getFirst() {
return _box.get(_box.keys.first);
}

bool countBoxKeys() {
if (_box.isOpen) {
final count = _box.getAll(_box.keys).cast().isNotEmpty;

return count;
}

return false;
}

@override
List getAll() {
return _box
.getAll(_box.keys)
.where((element) => element != null)
.cast()
.toList();
}

@override
void remove(String id) {
_box.delete(id);
}
}
```

I created a UserCacheModel and extend it from CacheModel like this:

```
final class UserCacheModel with CacheModel {
UserCacheModel({
required this.user,
});

UserCacheModel.empty() : user = const UserModel();

final UserModel user;

@override
CacheModel fromDynamicJson(json) {
final mapCast = json as Map?;
if (mapCast == null) return this;

return copyWith(userModel: UserModel.fromJson(mapCast));
}

@override
String get id => user.id.toString();

@override
Map toJson() {
return user.toJson();
}

UserCacheModel copyWith({UserModel? userModel}) {
return UserCacheModel(user: userModel ?? user);
}
}
```

Finally created a ProductCache which required CacheManager like this:

```
final class ProductCache {
ProductCache({required CacheManager cacheManager})
: _cacheManager = cacheManager;

final CacheManager _cacheManager;

Future init() async {
await _cacheManager.init(
cacheModels: [
CorporationCacheModel(corporation: const CorporationModel()),
UserCacheModel(user: const UserModel()),
],
);
}

late final HiveCacheOperation userCacheOperation =
HiveCacheOperation();

late final HiveCacheOperation
corporationCacheOperation = HiveCacheOperation();

}
```

But when i try to call .getAll function of userCacheOperation i got **"Invalid argument(s): Type mismatch. Expected UserCacheModel but got CorporationCacheModel."**.

So is this a registerAdapter error or something else?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.