Search code examples
flutterflutter-hive

Flutter loading custom list from Hive on application start failing with type 'List' is not a subtype of type 'List?' in type cast


I created a custom class in Hive:

@HiveType(typeId: 1)
class GeocodeLocationGoogleItem {
  @HiveField(0)
  String formattedAddress;
  @HiveField(1)
  String lat;
  @HiveField(2)
  String lng;
  @HiveField(3)
  DateTime lastUpdate;
  @HiveField(4)
  HourlyForcastWeatherbit hourlyForcast;

  GeocodeLocationGoogleItem(this.formattedAddress, this.lat, this.lng,
      this.lastUpdate, this.hourlyForcast);
}

I then store a list of these like so:

  void saveLocationsToMemory() async {
    //open box
    var box = await Hive.openBox<List<GeocodeLocationGoogleItem>>('weatherBox');

    //update list to storage
    box.put('weatherLocationList', weatherLocations);
  }

When I close my app and try and restart it I have it load all my adapters:

WidgetsFlutterBinding.ensureInitialized();
  await Hive.initFlutter();
  Hive.registerAdapter(GeocodeLocationGoogleItemAdapter());
  Hive.registerAdapter(HourlyForcastWeatherbitAdapter());
  Hive.registerAdapter(HourlyDataWeatherbitAdapter());

Then in my initState for my widget I have:

Provider.of<Settings>(context, listen: false).loadLocationsFromMemory();

When that runs I receive this error and my list is not loaded:

E/flutter (23601): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: type 'List' is not a subtype of type 'List?' in type cast E/flutter (23601): #0 BoxImpl.get (package:hive/src/box/box_impl.dart:44:26) E/flutter (23601): #1 Settings.loadLocationsFromMemory (package:dont_forget_the_weather/provider/settings_class.dart:66:28) E/flutter (23601): E/flutter (23601):

When I look at line 66 of settings.loadLocationsFromMemory I have this line:

weatherLocations = box.get("weatherLocationList", defaultValue: [])!;

The entire method looks like this:

void loadLocationsFromMemory() async {
    var box = await Hive.openBox<List<GeocodeLocationGoogleItem>>('weatherBox');

    weatherLocations = box.get("weatherLocationList", defaultValue: [])!;

    notifyListeners();
  }

Solution

  • SO after playing around I was able to kind of fox this with slight changes to my saving and loading to hive:

     void saveLocationsToMemory() async {
        //open box
        var box = await Hive.openBox<GeocodeLocationGoogleItem>('weatherBox');
        box.clear();
        //update list to storage
        for (var i = 0; i < weatherLocations.length; i++) {
          print(i);
          box.add(weatherLocations[i]);
        }
        notifyListeners();
      }
    
      void loadLocationsFromMemory() async {
        var box = await Hive.openBox<GeocodeLocationGoogleItem>('weatherBox');
    
        weatherLocations = box.values.toList();
    
        notifyListeners();
      }
    

    The odd thing is that this works on my emulator but does not work on my actual cell phone when I load it on my android device...It will not load.