I am developing a Flutter app with Getx State Management. I have Signin page and Dashboard page. I am maintaining all of my network url in another class. After 24 hours my token automatically expire and for this reason I am showing a dialog box that the token is expired and navigating user to login page.
After logging in with new credential I am getting new token and saving that token to my local storage. I am using Getx Storage package for local storage. But when I call the api from my desktop, in my log it is showing old token in my network request and token expired dialog is showing again and again.
If I do a full restart of my app then it is working fine.
This is my Sigin Controller method:
void signInApi() {
if (!formKey.currentState!.validate()) {
return;
}
formKey.currentState!.save();
isLoading.value = true;
Map data = {};
data = {'office_email': officeEmail.value, 'password': password.value};
_api.loginApi(data).then((value) {
isLoading.value = false;
if (value['error'] != null) {
Utils.customDialog(title: 'Login', message: value['error'], onOkTap: () {Get.back();});
} else {
String token = value['token'];
prefs.token.val = token;
prefs.email.val = officeEmail.value;
prefs.password.val = password.value;
Get.offNamed(RoutesName.dashboardScreen);
}
});
}
This is my SignIn repository:
class SignInRepository {
final _apiService = NetworkApiServices();
Future<dynamic> loginApi(var data) async {
dynamic response = await _apiService.postApi(data, AppUrl.loginApi);
return response;
}
}
This is my Dashboard Controller method:
void getEmployeeInfo() {
setRequestStatus(Status.loading);
_api.employeeInfo().then((value) {
if (value['error'] != null) {
Utils.customDialog(
title: 'Warning!',
message: value['error'],
isCancelable: false,
onOkTap: () {
Get.back();
box.erase();
Get.offAllNamed(RoutesName.loginView);
});
} else {
if (value['show_profile_publicly'] == '1') {
prefs.visibility.val = 'Public';
} else {
prefs.visibility.val = 'Private';
}
employeeInfo.value = UserProfile.fromJson(value['data']);
}
}).onError((error, stackTrace) {
debugPrint('Error from $runtimeType: $error');
setRequestStatus(Status.error);
setError(error.toString());
});
}
This is my Dashboard repository:
class DashboardRepository {
final _apiService = NetworkApiServices();
Future<dynamic> employeeInfo() async {
dynamic response = await _apiService.getApi(AppUrl.employeeInfoApi);
return response;
}
Future<dynamic> ratingInfo() async {
dynamic response = await _apiService.getApi(AppUrl.ratingInfoApi);
return response;
}
Future<dynamic> notificationInfo() async {
dynamic response = await _apiService.getApi(AppUrl.supportNotificationApi);
return response;
}
}
This is my AppUrl Class:
class AppUrl {
static String token = Get.find<MyPrefs>().token.val;
static const String baseUrl = 'https://api.something.ac';
// Login api
static const String loginApi = '$baseUrl/auth/login';
// Dashboard
static final String employeeInfoApi = '$baseUrl/profile?token=$token';
static final String ratingInfoApi = '$baseUrl/profile-rating?token=$token';
static final String supportNotificationApi = '$baseUrl/profile/ticket-assign-notification?token=$token';
}
This is my MyPrefs Class:
class MyPrefs extends GetxController {
Future<void> initStorage() async {
await GetStorage.init();
}
// App value
final token = ''.val('token');
final password = ''.val('password');
final email = ''.val('email');
final userId = 0.val('user_id');
final name = ''.val('name');
final photo = ''.val('photo');
final tempId = 0.val('tempId');
final visibility = ''.val('visibility');
// Preferences
final remember = false.val('remember_pass');
}
I have tried erasing GetStorage box but no result.
I manually deleted my all controller and single Dashboard controller but no result.
I have used Get.off to delete the controller automatically.
2
Answers
Finally I got the solution. In my AppUrl class I have the url declaration like below:
The problem was final keyword. I have declared my url final for this reason it was storing my previous token. Althogh I updated token in sign in page controller but my updated token was not set because of final keyword. After updating my AppUrl class urls like below:
my updated token is working fine.
Check this example, which do basically what you do with your token:
now make that token a getter or a method:
In the first example you are referencing a static variable, it calls your GetIt.find method once and never again, because its a variable, that value is stored there, by making it a getter or a method and calling it it will do all the logic inside again each time you call it, so if the token changed it will do that logic to get the new one