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;
}
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))
I think your result type is of type
UserLoginResponseEntity
so you are not encoding aMap
try printing yourresult.data
to check the data inside the object and the data type