How to save a response data into sharedPreference in flutter

I want to save the user details response in sharedPreference so that user can resume the app anytime as long as he/she doesn’t log out but this keeps on returning null when I tried to retrieved the data that I stored in sharedpreference. I don’t really know how to go about it.

This is the data that my backend returned after a successful login:

{"message":"Login Successfully","data":{"id":1,"type":1,"name":"Elijah","email":"[email protected]","profileImage":"http://192.168.229.108:8080/download/887c17f8-1f45-450e-8e45-a12b8a307e5a","accessToken":"OPXI5X98lcdvjUjgRiZTYvcDSjH2"},"code":200}

If I try to print the result.toString in the asyncPostData method, I get the instance of UserLoginResponseEntity and result.data is returning the instance of UserItem instead of the json data. All I need is to know how to store the “data” item which contains name, email, etc of the logged in user in sharedPreference. The “data” item is a json object that contains all the user’s info as shown in the response

class AppApi {
  static login({LoginRequestEntity? loginRequestEntity}) async {
    var response = await NetworkRequestUtil().post(
      AppConstants.LOGIN_URL,
      data: loginRequestEntity!.toJson(),
    );
    return UserLoginResponseEntity.fromJson(response);
  }
}


Future<void> asyncPostData(LoginRequestEntity loginRequestEntity) async {
    var result = await AppApi.login(loginRequestEntity: loginRequestEntity);
    if (result.code == 200) {
      try {
        //method to save the user data in sharedpreference
         Global.service.setString(
             AppConstants.STORAGE_USER_PROFILE_KEY, jsonEncode(result.data));

        if (context.mounted) {
          Navigator.of(context)
              .pushNamedAndRemoveUntil("/home", (route) => false);
        }
      } catch (e) {
        print("Local storage info saving error ${e.toString()}");
      }
    } else {
      toastInfo(msg: "Error Occurred");
    }
  }

class UserLoginResponseEntity {
  int? code;
  String? msg;
  UserItem? data;

  UserLoginResponseEntity({
    this.code,
    this.msg,
    this.data,
  });

  factory UserLoginResponseEntity.fromJson(Map<String, dynamic> json) =>
      UserLoginResponseEntity(
          code: json["code"],
          msg: json["message"],
          data: UserItem.fromJson(json["data"]));
}

class UserItem {
  String? token;
  String? name;
  String? description;
  String? avatar;
  int? type;
  String? email;

  UserItem({
    this.token,
    this.name,
    this.description,
    this.avatar,
    this.type,
    this.email,
  });

  factory UserItem.fromJson(Map<String, dynamic> json) => UserItem(
      token: json["accessToken"],
      name: json["name"],
      avatar: json["profileImage"],
      type: json["type"],
      email: json["email"]);

  Map<String, dynamic> toJson() => {
        "accessToken": token,
        "name": name,
        "profileImage": avatar,
        "type": type,
        "email": email
      };
}


class StorageService {
  late SharedPreferences _pref;
  Future<StorageService> initSharedPreference() async {
    _pref = await SharedPreferences.getInstance();
    return this;
  }

//method to return the stored user data if it's not null
//this method always returns null I don't know why my data wasn't saved in sharedpreference
UserItem? getUserProfile() {
    var offlineProfile =
        _pref.getString(AppConstants.STORAGE_USER_PROFILE_KEY) ?? "";
    if (offlineProfile.isNotEmpty) {
      UserItem.fromJson(jsonDecode(offlineProfile));
    }
    return null;
  }

  • I think your result type is of type UserLoginResponseEntity so you are not encoding a Map try printing your result.data to check the data inside the object and the data type

    – 

This seems to be an information from a class. According to your question, I found that result.data is a class named UserItem and result is a class named UserLoginResponseEntity.

If your question is how to convert this as a json text, you can follow the instructions below

To convert a class to Json

result.data.toJson();

This is convert result.data to Map<String, dynamic>

for get Map<String, dynamic> as String, try

json.encode(mapObject);

OR

json.decode(encodedObject);

for get String as Map<String, dynamic>

then for saving string you can use Hive or Shared Preferences

Update your class to override the toString medthod, this would display your class in a readable formart when you print:

class UserLoginResponseEntity {
  int? code;
  String? msg;
  UserItem? data;

  UserLoginResponseEntity({
    this.code,
    this.msg,
    this.data,
  });

  factory UserLoginResponseEntity.fromJson(Map<String, dynamic> json) =>
      UserLoginResponseEntity(
          code: json["code"],
          msg: json["message"],
          data: UserItem.fromJson(json["data"]));

  @override
  String toString() {
    return 'UserLoginResponseEntity{code: $code, msg: $msg, data: $data}';
  }
}

class UserItem {
  String? token;
  String? name;
  String? description;
  String? avatar;
  int? type;
  String? email;

  UserItem({
    this.token,
    this.name,
    this.description,
    this.avatar,
    this.type,
    this.email,
  });

  factory UserItem.fromJson(Map<String, dynamic> json) => UserItem(
      token: json["accessToken"],
      name: json["name"],
      avatar: json["profileImage"],
      type: json["type"],
      email: json["email"]);

  Map<String, dynamic> toJson() => {
        "accessToken": token,
        "name": name,
        "profileImage": avatar,
        "type": type,
        "email": email
      };

  @override
  String toString() {
    return 'UserItem{token: $token, name: $name, description: $description, avatar: $avatar, type: $type, email: $email}';
  }
}

But you can’t save a dart class using shared preferences but you can save strings to do that DO NOT use the classes toString method, do this instead:

use the toJson method in UserItem to convert result.data to Map<String, dynamic> then encode that data to a json String like so:

final userItemJsonString =  json.encode(result.data.toJson());

to get the UserItem object back from shared pref. decode the json String that is returned:

final userItem = UserItem.fromJson(json.decode(userItemJsonString))

Leave a Comment