I am using provider package for state management system...I am trying to update value using proxy provider but my value is updating after calling api but I wanted to to update value before api call following is my main.dart where I am using proxy provider and trying to get value from change notifier
void main() {
Provider.debugCheckInvalidValueType = null;
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
// final auth = Auth();
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (_) => Auth(),
),
ProxyProvider<Auth, ApiCalls>(
//create: (_) => ApiCalls(),
update: (_, auth, __) => ApiCalls(auth.token)),
//ApiCalls(auth.token)),
ChangeNotifierProvider(
create: (_) => FlutterFunctions(),
),
],
child: Consumer<Auth>(
builder: (context, value, _) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: value.isAuth
? const AdminScreen()
: FutureBuilder(
future: value.tryAutoLogin(),
builder: (context, snapshot) =>
snapshot.connectionState == ConnectionState.waiting
? CircularProgressIndicator()
: const AdminLoginScreen(),
following is my Auth class with change notifier where I am updating value
class Auth extends ChangeNotifier {
String? accessToken;
DateTime? accessTokenExpiryDate;
String? get token {
if (accessTokenExpiryDate != null &&
accessTokenExpiryDate!.isAfter(DateTime.now()) &&
accessToken != null) {
return accessToken;
} else if (accessTokenExpiryDate!.isBefore(DateTime.now())) {
return accessToken;
}
return null;
}
Future<void> restoreAccessToken() async {
print('restoreAccessToken started');
//print(token);
final url = '${Ninecabsapi().urlHost}${Ninecabsapi().login}/$sessionId';
var response = await http.patch(
Uri.parse(url),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'Authorization': accessToken!
},
body: json.encode(
{"refresh_token": refreshtoken},
),
);
var userDetails = json.decode(response.body);
if (response.statusCode == 401) {
print(userDetails['messages']);
}
sessionId = userDetails['data']['session_id'];
accessToken = userDetails['data']['access_token'];
accessTokenExpiryDate = DateTime.now().add(
Duration(seconds: userDetails['data']['access_token_expiry']),
);
refreshToken = userDetails['data']['refresh_token'];
refreshTokenExpiryDate = DateTime.now().add(
Duration(seconds: userDetails['data']['refresh_token_expiry']),
);
final userData = json.encode({
'sessionId': sessionId,
'refreshToken': refreshToken,
'refreshExpiry': refreshTokenExpiryDate!.toIso8601String(),
'accessToken': accessToken,
'accessTokenExpiry': accessTokenExpiryDate!.toIso8601String()
});
//print(userDetails);
notifyListeners();
final prefs = await SharedPreferences.getInstance();
prefs.setString('userData', userData);
print("this is from restoreAcessToken :$userDetails");
final extractData =
json.decode(prefs.getString('userData')!) as Map<String, dynamic>;
print('restore access token: ${extractData['accessToken']}');
reset();
}
following is my ApiCalls class where I want to use updated token when retry
class ApiCalls extends ChangeNotifier {
final String? token;
ApiCalls(this.token);
Future<void> postVehicles(BuildContext context, String vehicleType) async {
print('postVehicles:$token');
final prefs = await SharedPreferences.getInstance();
final extractData =
json.decode(prefs.getString('userData')!) as Map<String, dynamic>;
var data = {"vehicletype": vehicleType, "filename": vehicleType};
Map<String, String> obj = {"attributes": json.encode(data).toString()};
var flutterFunctions =
Provider.of<FlutterFunctions>(context, listen: false);
final url = Ninecabsapi().urlHost + Ninecabsapi().getvehicle;
try {
loading();
var response = http.MultipartRequest("POST", Uri.parse(url))
..files.add(await http.MultipartFile.fromPath(
"imagefile", flutterFunctions.imageFile!.path,
contentType: MediaType("image", "jpg")))
//..headers['Authorization'] = token!
..fields.addAll(obj);
final client = RetryClient(
http.Client(),
retries: 2,
when: (response) {
return response.statusCode == 401 ? true : false;
},
onRetry: (req, res, retryCount) async {
//print('retry started $token');
if (retryCount == 0 && res?.statusCode == 401) {
// Only this block can run (once) until done
await Provider.of<Auth>(context, listen: false)
.restoreAccessToken();
req.headers['Authorization'] = token!;
// extractData['accessToken']
//token = authProvider.token;
print('retry started ${extractData['accessToken']}');
//req.headers.clear();
}
},
);
final send = await client.send(response);
final res = await http.Response.fromStream(send);
switch (res.statusCode) {
case 201:
Future.delayed(Duration.zero)
.then((value) => showsnackbar(context, "Vehicle type inserted"));
}
var messages = json.decode(res.body);
print("this is from sample $messages");
loading();
in following image you can see my token is updated in ui here my token is updated following is the response from the restoreaccesswoken method and you can see I am not Abel to use updated token in headers and I am also printing the token in print statement it is not printing updated token you can see my response here