I have returned to Flutter after while (in the meantime null safety was introduced). I ended up with a need to update a project. Let's say in that project I have a User model. I managed to update most of the project but the part that gives me a headache is logout action. There is a need to clear the user (after logout) which I need to set up as null or empty it otherwise, but of course I am getting an error:
Unhandled Exception: type 'Null' is not a subtype of type 'User'
So my question here is what is the best strategy to clear not only user but any other models I have for a redux state without hitting this problem with models not being able to be null?
User model:
class User {
String id;
String username;
String email;
String jwt;
User({ required this.id, required this.username, required this.email, required this.jwt });
factory User.fromJson(Map<String, dynamic> json) {
return User (
id: json['id'],
username: json['username'],
email: json['email'],
jwt: json['jwt']
);
}
}
User actions:
/* User actions */
ThunkAction<AppState> getUserAction = (Store<AppState> store) async {
final prefs = await SharedPreferences.getInstance();
final String? storedUser = prefs.getString('user');
final user = storedUser != null ? User.fromJson(json.decode(storedUser)) : null;
if(user != null) {
store.dispatch(GetUserAction(user));
}
};
ThunkAction<AppState> logoutUserAction = (Store<AppState> store) async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('user');
var user;
store.dispatch(LogoutUserAction(user));
};
class GetUserAction {
final User _user;
User get user => this._user;
GetUserAction(this._user);
}
class LogoutUserAction {
final User _user;
User get user => this._user;
LogoutUserAction(this._user);
}
NOTE: see how I managed to go about the null in the getUserAction (login) part. I just don't dispatch the action if it is null, however I can not do this in the logout as I need explicitly to set the user to null (clear it) and that way log it out from the app.
Can I make a model accept null values? How would I go about this? Or is there any other way I should go about this? Thank you for your kind answer.
CodePudding user response:
Change your model to:
class User {
String? id;
String? username;
String? email;
String? jwt;
User({ required this.id, required this.username, required this.email, required this.jwt });
factory User.fromJson(Map<String, dynamic> json) {
return User (
id: json['id'] ?? "",
username: json['username'] ?? "",
email: json['email'] ?? "",
jwt: json['jwt'] ?? ""
);
}
}
And you need check null_safety for all variable with operation ??
After logout you can check user null with user.id == ""
or user == User()
ThunkAction<AppState> logoutUserAction = (Store<AppState> store) async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('user');
var user = User();
store.dispatch(LogoutUserAction(user));
};