isar / hive

Lightweight and blazing fast key-value database written in pure Dart.
Apache License 2.0
3.97k stars 393 forks source link

the getter isn't defined for the type 'hiveobjectmixin' #761

Open pishguy opened 2 years ago

pishguy commented 2 years ago

After creating model to make a relationship between 2 models i can't get field data from nested relationship

I have a User model which that contain other model as Transactions which that's a HiveList, now when i try to get a field such as cost from Transaction with below code:

final Box<User> _user = Hive.box<User>('user');
print('${_user.values.first.transactions.first.cost}');

i get this error:

error: The getter 'cost' isn't defined for the type 'HiveObjectMixin'. (undefined_getter at [xxxx] lib/src/screens/dashboard/tabs/screen_transactions.dart:85)

Models:

@HiveType(typeId: 1)
class User extends HiveObject {
  @HiveField(0)
  late String nameFamily;

  @HiveField(1)
  late String apiToken;

  @HiveField(2)
  late String mobileNumber;

  @HiveField(3)
  late HiveList transactions;
}
@HiveType (typeId: 4)
class Transactions extends HiveObject {
  @HiveField(0)
  late int cost;

  @HiveField(1)
  late int type;

  @HiveField(2)
  late String dateTime;
}

Adapters:

class UserAdapter extends TypeAdapter<User> {
  @override
  final int typeId = 1;

  @override
  User read(BinaryReader reader) {
    final numOfFields = reader.readByte();
    final fields = <int, dynamic>{
      for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return User()
      ..nameFamily = fields[0] as String
      ..apiToken = fields[1] as String
      ..mobileNumber = fields[2] as String
      ..address = (fields[3] as HiveList).castHiveList()
      ..wallet = (fields[4] as HiveList).castHiveList()
      ..transactions = (fields[5] as HiveList).castHiveList();
  }

  @override
  void write(BinaryWriter writer, User obj) {
    writer
      ..writeByte(6)
      ..writeByte(0)
      ..write(obj.nameFamily)
      ..writeByte(1)
      ..write(obj.apiToken)
      ..writeByte(2)
      ..write(obj.mobileNumber)
      ..writeByte(3)
      ..write(obj.transactions);
  }

  @override
  int get hashCode => typeId.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is UserAdapter &&
          runtimeType == other.runtimeType &&
          typeId == other.typeId;
}
class WalletAdapter extends TypeAdapter<Wallet> {
  @override
  final int typeId = 3;

  @override
  Wallet read(BinaryReader reader) {
    final numOfFields = reader.readByte();
    final fields = <int, dynamic>{
      for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
    };
    return Wallet()..total = fields[0] as int;
  }

  @override
  void write(BinaryWriter writer, Wallet obj) {
    writer
      ..writeByte(1)
      ..writeByte(0)
      ..write(obj.total);
  }

  @override
  int get hashCode => typeId.hashCode;

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is WalletAdapter &&
          runtimeType == other.runtimeType &&
          typeId == other.typeId;
}
bit-garden commented 2 years ago
final Box<User> _user = Hive.box<User>('user');
print('${(_user.values.first.transactions.first as Transactions).cost}')

Hive doesn't always spit out the expected type because of Dart limitations. Just cast to expected type.