I have a method login in my Provider class which is called in initState() method of my HomeScreen(), in login function I basically register/check if a user information is stored in server or not, and then I post request to server to get that user's info. Everything is working fine but when I hot restart or reopens the app, it keeps on loading because obviously the ternary operation doesn't satisfy but If I print the data inside the login function, it does get changed, so as a result, the notifyListeners() is not working properly and hence the state is not getting changed. (Right now I have to hot reload ctrl+s, and then the state changes and everything loads successfully).
HomeScreen():
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<Course> courses = [];
@override
void initState() {
super.initState();
courses = Course().getAllCourses();
Future.delayed(Duration.zero, () async {
Provider.of<LoginProvider>(context, listen: false).login();
});
}
@override
Widget build(BuildContext context) {
bool isLoading =
Provider.of<LoginProvider>(context, listen: false).isLoading;
User user = Provider.of<LoginProvider>(context, listen: false).user;
print("INITIAL: $isLoading");
print("INITIAL: ${user.data!.categoryList!.length}");
return Scaffold(
backgroundColor: Colors.white,
body: !isLoading && user.data != null
? ListView.separated(
itemCount: courses.length,
separatorBuilder: (context, index) {
return Divider();
},
itemBuilder: (context, index) {
final course = courses[index];
final courseNew = user.data!.categoryList![index];
print("INSIDE: $isLoading");
print("INSIDE: ${user.data!.categoryList!.length}");
if (courses.length == user.data!.categoryList!.length) {
return ... // full custom
}
return Center(
child: Text("No Data recieved from backend"),
);
},
)
: Center(
child: CircularProgressIndicator(
strokeWidth: 4,
)),
);
}
}
(Both courses and user.data.categoryList have same length)
Login function in Provider file:
login() async {
await _checkIsUserLoggedIn();
if (_deviceDetails.deviceID == "") {
print("[INFO] NEW USER DEVICE DETECTED");
print("[INFO] LOGGING IN...");
await _getDeviceDetails();
// fetching platform details, if success, carry-on, else throw error
try {
if (_deviceDetails.deviceID != "") {
// post request to server
Map<String, dynamic> requestBody = {
'device_id': _deviceDetails.deviceID
};
http.Response response = await http
.post(Uri.parse(Constants.LOGIN_ENDPOINT), body: requestBody);
_user = userFromJson(response.body);
_deviceDetails.userID = _user.data!.userId!;
_deviceDetails.userName = _user.data!.name!;
_deviceDetails.token = _user.data!.token!;
await _saveLoginDetails(_deviceDetails);
print("[INFO] USER LOGGED IN SUCCESSFULLY");
}
} catch (error) {
print("[INFO] ERROR WHILE FETCHING DEVICE DETAILS: $error");
}
} else {
print("[INFO] THIS USER DEVICE IS ALREADY LOGGED IN");
print("[INFO] FETCHING EXISTING USER DETAILS");
Map<String, dynamic> requestBody = {'device_id': _deviceDetails.deviceID};
http.Response response = await http
.post(Uri.parse(Constants.LOGIN_ENDPOINT), body: requestBody);
_user = userFromJson(response.body);
print("INSIDE LOGIN FUNCTION: ${_user.data!.categoryList!.length}"); // prints 2 in console (correct)
}
_isLoading = false;
notifyListeners();
}
Console output:
Output when app first loads or Hot Restart:
I/flutter ( 3495): INITIAL: true
I/flutter ( 3495): INITIAL: 1
I/flutter ( 3495): [INFO] THIS USER DEVICE IS ALREADY LOGGED IN
I/flutter ( 3495): [INFO] FETCHING EXISTING USER DETAILS
I/flutter ( 3495): INSIDE LOGIN FUNCTION: 2
Ouput when app Hot Reloads (Ctrl+S):
I/flutter ( 3495): INITIAL: false
I/flutter ( 3495): INITIAL: 2
I/flutter ( 3495): INSIDE: false
I/flutter ( 3495): INSIDE: 2
I/flutter ( 3495): INSIDE: false
I/flutter ( 3495): INSIDE: 2
As you can see, after hot reloading, the state changes but not without it, so that means notifyListeners() is not behaving properly in login function?
What could possible be wrong here, I'm really confused...
Any help would be really appreciated!