Search code examples
jsonflutterserializationsharedpreferencesdeserialization

flutter error while trying to retrieve a Map from sharedPreferences


I'm trying to retrieve a Map<String, List<Result>> saved in sharedPreferences using sharedPreferences.setString('key', json.encode(myMap)).
The methods toJson() and fromJson() already exist in the MyObj class.
When i try to retrieve this map using json.decode(sharedPreferences.getString('key')) i get the error Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Map<String, List<Result>>'

How can i solve this?

Result class:

class Result {
  final String position;
  final String points;
  final Driver driver

  Result({this.position, this.points, this.driver});

  factory Result.fromJson(Map<String, dynamic> json) {
    return Result(
      position: json['position'],
      points: json['points'],
      driver: Driver.fromJson(json['Driver']),
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'position': position,
      'points': points,
      'driver': driver,
    };
  }
}

Method to retrieve Map in sharedPreferences:

Future<Map<String, List<Result>>> fetchResult() async {
    SharedPreferences sharedPreferences = await getSharedPreferencesInstance();
    Map<String, List<Result>> results = Map<String, List<Result>>();
    if (sharedPreferences.getString('results') != null) {
      results = Map<String, dynamic>.from(json.decode(sharedPreferences.getString('results')));
      return results;
    } else {
        final response = await dio.get(Constants.resultUrl('2021', (i + 1).toString()));
        final data = response.data;
        List<Result> singleResult = [];
        for(...){
            for (int j = 0; j <= 19; j++) {
                    singleResult.add(Result.fromJson(
                        data['Test']['Table']['Races'][0]['Results'][j]));
                  }
                }
                results[data['Test']['Table']['Races'][i]['name']] =
                    singleResult;
        }
        sharedPreferences.setString('results', json.encode(results));
        return results;
      } else {
        throw Exception("Fail!");
      }
    }
  }

New error:

E/flutter ( 4645): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception: NoSuchMethodError: The method '[]' was called on null.
E/flutter ( 4645): Receiver: null
E/flutter ( 4645): Tried calling: []("firstName")

firstName it's a String in Driver class.

Driver class:

class Driver {
  final String firstName;
  final String secondName;
  final String dateOfBirth;
  final String nationality;

  Driver(
      {this.firstName,
      this.secondName,
      this.dateOfBirth,
      this.nationality});

  factory Driver.fromJson(Map<String, dynamic> json) {
    return Driver(
      firstName: json['firstName'],
      secondName: json['secondName'],
      dateOfBirth: json['dateOfBirth'],
      nationality: json['nationality'],
    );
  }

  Map<String, dynamic> toJson() {
    return {
      'firstName': firstName,
      'secondName': secondName,
      'dateOfBirth': dateOfBirth,
      'nationality': nationality,
    };
  }

Solution

  • Change this code:

    results = Map<String, dynamic>.from(json.decode(sharedPreferences.getString('results')));
    return results;
    

    To this:

    final decodedJson = Map<String, List<dynamic>>.from(json.decode(sharedPreferences.getString('results')));
    
    for (var entry in decodedJson.entries) {
      final resultList = <Result>[];
      for (var eachResult in entry.value) {
        resultList.add(Result.fromJson(eachResult));
      }
      results[entry.key] = resultList;
    }
    
    return results;
    

    Solution of new error: You misspelled the key of your json parameter in Result.fromJson() constructor. It should be Driver.fromJson(json['driver']) instead of Driver.fromJson(json['Driver']).