Search code examples
flutterdartflutter-hive

Type inferring doesn't work properly when saving List of objects in Hive box


I have a list of hive objects i need to save, within whiche there is another list of hive objects, for example:

@freezed
class CorrectionDestination extends HiveObject with _$CorrectionDestination {
  CorrectionDestination._();

  @HiveType(typeId: 4)
  factory CorrectionDestination({
    @HiveField(0) required int stepId,
    @HiveField(1) required String stepTitle,
    @HiveField(2) required String stepType,
    @HiveField(3) required bool isCurrentStep,
    @HiveField(4) required int projectStepId,
    @HiveField(5)
    @JsonKey(defaultValue: [])
    required List<DestinationResults> results,
  }) = _CorrectionDestination;

  factory CorrectionDestination.fromJson(Map<String, dynamic> json) =>
      _$CorrectionDestinationFromJson(json);
}

and my destination results looks like

@freezed
class DestinationResults extends HiveObject with _$DestinationResults {
  DestinationResults._();

  @HiveType(typeId: 5)
  factory DestinationResults({
    @HiveField(0) required int stepResultId,
    @HiveField(1) required String stepResultTitle,
  }) = _DestinationResults;

  factory DestinationResults.fromJson(Map<String, dynamic> json) =>
      _$DestinationResultsFromJson(json);
}

The problem occurs when im trying to cast the List to List:

final box = await Hive.openBox<List<CorrectionDestination>>('correctionDestinations');

Althought i can clearly see the object from the print statement (if we'll remove generic type from the openBox function):

final availableDestinations = box.get(inspectionId);
print(availableDestinations);

I've double checked my adapters and have following flutter doctors output:

[✓] Flutter (Channel stable, 3.16.3, on macOS 14.2 23C64 darwin-arm64, locale en-UA)
    • Flutter version 3.16.3 on channel stable at /Users/lesha/fvm/versions/3.16.0
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision b0366e0a3f (5 weeks ago), 2023-12-05 19:46:39 -0800
    • Engine revision 54a7145303
    • Dart version 3.2.3
    • DevTools version 2.28.4


Solution

  • That is expected, because the list you're getting from Hive is considered as "collection from an external data source".

    See Invalid casts, on this part:

    In cases where you are working with a collection that you don’t create, such as from JSON or an external data source, you can use the cast() method provided by Iterable implementations, such as List.

    Here’s an example of the preferred solution: tightening the object’s type.

    Map<String, dynamic> json = fetchFromExternalSource();
    var names = json['names'] as List;
    assumeStrings(names.cast<String>());