Reputation: 742
It seems my UI is not updating the changes after I have patched the info over the API. I'm using Provider
for state management. Here is the code:
UPDATE: Changed the data to be an object as send it as one to the API endpoint
UserModel :
class UserData{
String name,
surname,
birthDate;
UserData({
this.generalEmail,
this.surname,
this.primaryPhone,
});
UserData.fromJson(Map<String, dynamic> json) {
name= json['name'];
surname = json['surname'];
birthDate= json['birthDate'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data['name'] = this.name;
data['surname'] = this.surname;
data['birthDate'] = this.birthDate;
return data;
}
}
User Store:
class UserStore extends ChangeNotifier {
Map<String, UserData> _userInfo = {};
Map<String, UserData> get userInfo => _userInfo ;
void updateUserInfo(UserData user) {
_userInfo[user.userId] = user;
notifyListeners();
}
UserData getUserInfoByUserId(String userId) => _userInfo[userId];
}
And the service action for the User Store:
UserStore userStore;
BuildContext context;
UserActions(BuildContext context) {
this.context = context;
this.userStore = Provider.of<UserStore>(context, listen: false);
}
Future<HTTPResponse<UserData>> patchUserInfo(UserData user) async {
final response = await ApiRequest(Method.PATCH, '/users',
body: jsonEncode(user.toJson()));
dynamic body = jsonDecode(response.body);
if (response.statusCode == 200) {
dynamic data = body['data'];
UserData user = UserData();
if (data != null) {
user = UserData.fromJson(data);
}
return HTTPResponse<UserData>(
isSuccessful: true,
data: user,
message: HTTPResponse.successMessage,
statusCode: response.statusCode,
);
} else {
return HTTPResponse<UserData>(
isSuccessful: false,
data: null,
message: body['message'] ?? HTTPResponse.errorMessage,
statusCode: response.statusCode,
);
}
}
Future<void> changeUserInfo(UserData user) async {
final userRes = await patchUserInfo( // call the API and pass the data
user);
if (userRes != null) {
userStore.updateUserInfo(user);
return;
}
userStore.updateUserInfo(user);
}
UI that is not updating:
final userStore = Provider.of<UserStore>(context, listen: false);
UserData user = userStore.getUserInfo(userId);
...
return Column(
children: [
Text(user.name), // only updates it when I refresh the widget
Text(user.surname), // only updates it when I refresh the widget
Text(user.birthDate), // only updates it when I refresh the widget
],
);
After the API goes through, I want to update my UI with the latest changes if not, don't update the UI. I'm not sure, but it's probably the updateUserInfo
method inside the UserStore that I'm not setting right in order to update the UI immediately after the successful API call. Where is my mistake? I can use indexWhere
when it's a list, but how do I update it then when the data model is a Map
like I defined it in the UserStore?
Thanks in advance for you help!
Upvotes: 0
Views: 273
Reputation: 9734
You are not listening to the changes in your Provider
(see: listen: false
). You can use the following code to get notified upon changes you make with updateUserInfo
:
return Consumer<UserStore>(builder: (context, UserStore userStore, child) {
UserData user = userStore.getUserInfo(userId);
return Column(
children: [
Text(user.name),
Text(user.surname),
Text(user.birthDate),
],
);
});
And use this when you get data from API (since here you don't need to listen):
context.read<UserStore>().updateUserInfo(userRes);
Create a provider like this, above the Consumer
:
return ChangeNotifierProvider(create: (context) => UserStore(), child: ...);
Upvotes: 1