Home > Blockchain >  Save nested objects in shared preferences
Save nested objects in shared preferences

Time:03-15

I have an object that contains a json array , which am trying to store in shared preferences but i don't know how to do so .

This is my model :

import 'dart:convert';

import 'package:deepnrise/models/settings/perimeter.dart';
import 'package:deepnrise/models/user/user_perims.dart';

UserWithPerim user(String str) => UserWithPerim.fromJson(json.decode(str));

class UserWithPerim {
  // ignore: non_constant_identifier_names
  UserWithPerim({
    required this.identifier,
    required this.firstName,
    required this.lastName,
    required this.email,
    required this.role,
    required this.perimeters,
  });

  String identifier;
  String firstName;
  String lastName;
  String email;
  String role;
  List<UserPerimeter> perimeters;

  factory UserWithPerim.fromJson(Map<String, dynamic> json) {
    return UserWithPerim(
      identifier: json['identifier'] ?? "",
      firstName: json['firstName'] ?? "",
      lastName: json['lastName'] ?? "",
      email: json['email'] ?? "",
      role: json['role'] ?? "",
      perimeters: (json['perimeters'] as List)
          .map((p) => UserPerimeter.fromJson(p))
          .toList(),
    );
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['identifier'] = identifier;
    data['firstName'] = firstName;
    data['lastName'] = lastName;
    data['role'] = role;
    data['email'] = email;
    data['perimeters'] = perimeters;
    return data;
  }
}







This the perimeters model :

import 'dart:convert';

Userperimeters(String str) => UserPerimeter.fromJson(json.decode(str));

String UserPerimToJson(UserPerimeter data) => json.encode(data.tojson());

class UserPerimeter {
  // ignore: non_constant_identifier_names
  UserPerimeter(
      {required this.id, required this.label, required this.perimeterId});
  // ignore: non_constant_identifier_names
  int id;
  String label;
  int perimeterId;

  factory UserPerimeter.fromJson(Map<String, dynamic> json) {
    return UserPerimeter(
        id: json['id'] ?? "",
        label: json['label'] ?? "",
        perimeterId: json["perimeterId"] ?? "");
  }

  Map<String, dynamic> tojson() => {
        "id": id,
        "label": label,
        "perimeterId": perimeterId,
      };
}






For now I've two models of my user object , one that contains the perils list and one that doesn't because whenever I try to store my user in shared prefs I get this exception thrown :

Unhandled Exception: type 'UserPerimeter' is not a subtype of type 'Map<String, dynamic>'



This is how am saving and reading my user:

  saveUser(value) async {
    final prefs = await SharedPreferences.getInstance();
    String user = jsonEncode(User.fromJson(value));
    prefs.setString(Preferences.USER_KEY, user);
  }

Future<User?> getUser() async {
    final prefs = await SharedPreferences.getInstance();
    if (prefs.containsKey(Preferences.USER_KEY)) {
      Map<String, dynamic> userMap =
          jsonDecode(prefs.getString(Preferences.USER_KEY) ?? "");
      User user = User.fromJson(userMap);
      return user;
    }
  }

Is there a way with which I can store the whole user model with the perils object list without making two models of the user object ? thank you so much in advance.

CodePudding user response:

Convert the list of perimeters to list of Json like this:

if (this.perimeters != null) {
          data['perimeters'] = this.perimeters!.map((v) => v.toJson()).toList();
        }

CodePudding user response:

The work around here to convert your whole json response to string. save that string into sharedprefs, then you can call it back and decode it using:

var response = json.decode(prefs.getString("response");

So, the full idea:

prefs.setString("response",json.encode(response.body));

using that String as json format again:

MyModel model = MyModel.fromJson(json.decode(prefs.getString("response")));

I hope you find what you need from this idea.

  • Related