I'm trying to use provider with an async function where I'm changing a value of variable and as soon as the value changes, I want all listeners to be notified.
I'm sending a post request and waiting for response in the below async function. I'm waiting for the response and depending on that I want to show message on the Stateful Widget.
The provider seems to change value of the variable but doesn't change state on Text
on the screen.
userloginprovider.dart
bool isLoading = false;
HttpService http = HttpService();
class UserLoginProvider with ChangeNotifier {
String loginMessage = '';
late UserAuthorizationResponse userRegistrationResponse;
Future loginUser(userData) async {
Response response;
print(loginMessage);
try {
isLoading = true;
response = await http.loginUser('api/v1/login/', userData);
isLoading = false;
if (response.statusCode == 200) {
var newReponse = response.data;
userRegistrationResponse =
UserAuthorizationResponse.fromJson(newReponse['data']);
loginMessage = newReponse['message'];
} else {
print('status code is not 200.');
}
} on Exception catch (e) {
isLoading = false;
loginMessage = e.toString().substring(11);
}
notifyListeners();
}
}
userloginscreen.dart
class _LoginPageState extends State<LoginPage> {
final UserLoginProvider userLoginProvider = UserLoginProvider();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ChangeNotifierProvider(
create: (context) => UserLoginProvider(),
child: Consumer<UserLoginProvider>(
builder: (context, provider, child) {
return Container(
padding: const EdgeInsets.all(8.0),
width: double.infinity,
height: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(provider.loginMessage.toString()), //<-- I want to change value here.
AuthorizationButtons(
fieldName: 'Username',
textEditingController: usernameController,
),
AuthorizationButtons(
fieldName: 'Password',
textEditingController: passwordController,
),
OutlinedButton(
onPressed: () {
userData = {
'username': usernameController.text,
'password': passwordController.text,
};
userLoginProvider.loginUser(userData);
},
child: const Text('Submit'),
)
],
),
);
},
),
),
);
}
}
CodePudding user response:
A new provider is created in every rebuild
body: ChangeNotifierProvider(
create: (context) => UserLoginProvider(),
Use the one in the state
body: ChangeNotifierProvider(
create: (context) => userLoginProvider,
CodePudding user response:
you are notifying the listeners when it fails which is in catch block:-
on Exception catch (e) {
isLoading = false;
loginMessage = e.toString().substring(11); //here
notifyListeners();
}
}
but if the code runs without the error(exception). you are not notifying it on your code. so,if you want to notify, try something like this
try {
isLoading = true;
response = await http.loginUser('api/v1/login/', userData);
isLoading = false;
if (response.statusCode == 200) {
var newReponse = response.data;
userRegistrationResponse =
UserAuthorizationResponse.fromJson(newReponse['data']);
loginMessage = 'something'; //here
} else {
print('status code is not 200.');
}
notifyListeners();//notify the listeners here