I have a form called Forms
that has an endDrawer
. Inside this form, I am using a provider
called GlobalsProvider
that stores all my global variables. One of them is pendingOutgoingTransactions
, which shows how many pending transactions are stored in sqflite
waiting to be sent to SQL Server.
class Forms extends StatefulWidget {
const Forms({super.key});
@override
State<Forms> createState() => _FormsState();
}
class _FormsState extends State<Forms> {
@override
Widget build(BuildContext context) {
return Consumer<GlobalsProvider>(
builder: (context, globals, child) => Scaffold(
appBar: //...
endDrawer: Drawer(
child: Column(
children: [
Expanded(flex: 16,
child: DrawerHeader(
child: Column(
children: [
Row(
children: [
const Text('Pending Transactions: ', style: TextStyle(fontSize: 20.0, color: Colors.grey),),
Text(globals.pendingOutgoingTransactions.toString(), style: const TextStyle(fontSize: 20.0),)
],
),
],
)
)
),
],
),
),
body: //...
)
)
);
}
}
When I go to another form and write to sqflite
then hit back to go to Forms
, this variable correctly increments by 1. I have a timer that fires every 30 seconds to send any pending transactions to SQL Server and, after sending, it decrements the pendingOutgoingTransactions
variable. This is the part that isn't working right. While I'm on the Forms
screen, I have the drawer opened and I don't see the value going down. It just stays at 1. Below are the relevant parts of GlobalsProvider
.
GlobalsProvider:
class GlobalsProvider extends ChangeNotifier {
Timer? localDBOutgoingStreamTimer; ///Used to continuously send data from localDB to SQL Server
int pendingOutgoingTransactions = 0;
Future<Map<String, dynamic>> writeToLocalDB() async {
Map<String, dynamic> returnMap = {};
//...write...
final physInvRows = await localDBQueryRowCount(table: myTable); //Gets the current number of pending rows
pendingOutgoingTransactions = physInvRows;
notifyListeners();
return returnMap;
}
void localDBStartOutgoingStream() {
localDBOutgoingStreamTimer = Timer.periodic(const Duration(seconds: 30), (Timer t) => localDBOutgoingStream());
notifyListeners();
}
void localDBOutgoingStream() async {
//...send any rows to SQL Server...
final physInvRowsAfter = await localDBQueryRowCount(table: myTable);
pendingOutgoingTransactions = physInvRowsAfter;
notifyListeners();
}
Login Screen:
class Login extends StatefulWidget {
const Login({super.key});
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
final globalsClass = GlobalsProvider();
@override
void initState() {
super.initState(); ///Run this first
initialize();
}
@override
dispose() {
super.dispose(); ///Run this last
}
void initialize() async {
globalsClass.localDBStartOutgoingStream();
if (serverList.isNotEmpty) {
//...runs a function that runs "setState(() {})" at the end
}
}
@override
Widget build(BuildContext context) {
return Consumer<GlobalsProvider>(
builder: (context, globals, child) => Scaffold(
appBar: //...
body: //...
)
);
}
}
Main:
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => GlobalsProvider(),
child: GetMaterialApp(
title: 'My App',
home: const MyHomePage(title: 'My App',),
),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return const Wrapper();
}
}
For now try this so you're sure its the same object
class Login extends StatefulWidget {
const Login({super.key});
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
@override
void initState() {
super.initState(); ///Run this first
initialize();
}
@override
dispose() {
super.dispose(); ///Run this last
}
void initialize() async {
/// initialize the variable here nad use it only here,
/// I don't know where or how globalsClass is created in your app
final globalsClass = Provider.of<GlobalsProvider>(context, listen: false);
globalsClass.localDBStartOutgoingStream();
if (serverList.isNotEmpty) {
//...runs a function that runs "setState(() {})" at the end
}
}
@override
Widget build(BuildContext context) {
return Consumer<GlobalsProvider>(
builder: (context, globals, child) => Scaffold(
appBar: //...
body: //...
)
);
}
}