I’m developing a Flutter app where I have a ChangeNotifier service that manages file upload processes. This service has a boolean isUploading property that tracks whether files are currently being uploaded. I’m trying to reflect the upload state in the UI by changing an icon in the AppBar of a FileViewPage widget based on isUploading.
My app structure includes a MultiProvider at the top level in the main function:
void main() { // Main function is the base of the app I need the icon change in the next page not here.
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => SharedFilesProvider()),
ChangeNotifierProvider(create: (_) => CloudService()),
],
child: MyApp(), // MyApp is the root widget of your application
),
);
}
On the next page (which is a few navigation steps into the app), I’m trying to use the state of isUploading to toggle between two icons in the AppBar:
final isUpdating = context.watch<CloudService>().isUploading ?? false;
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
icon: Icon(
isUpdating ? Icons.cloud_upload_outlined : Icons.cloud_queue_outlined,
color: Colors.white,
),
onPressed: () => {},
),
],
),
);
In CloudService, the isUploading state changes within a pushChanges method, which performs asynchronous file uploads and updates isUploading accordingly:
class CloudService extends ChangeNotifier {
bool? _isUploading;
bool? get isUploading => _isUploading;
// Method to push changes, updates _isUploading and calls notifyListeners()
Future<void> pushChanges() async {
_isUploading = true;
notifyListeners();
// Simulated file upload process
await Future.delayed(Duration(seconds: 2));
_isUploading = false;
notifyListeners();
}
}
The icon does not update dynamically when isUploading changes. I expect the icon to switch to Icons.cloud_upload_outlined when isUploading is true and back to Icons.cloud_queue_outlined when false, but the icon remains static once the page is loaded.
I performed a hot restart to ensure it’s not a hot reload issue, and I’ve confirmed through debugging that notifyListeners() is being called as expected when isUploading changes.
I think I couldn’t connect provider with appBar.
It is not changing false to true while uploading.
2
Answers
Well after many trials I found out that I am actually getting the data back from CloudService class. When I call the class's method like this from initState:
final isUpdating = Provider.of(context,listen: false); isUpdating.initialize();
The way I found it was an unrelated button click, that button click has nothing to do with this sequence of functions but, opens a sub menu in the view and closes it with a setState.
When setState works the iconButton does the necessary update on its icon value. Problem now is how to make setState work when this function is working... @pcba-dev
initState
is a method which is called when a stateful widget is inserted into the widgets tree. It is useful for performing initialization tasks that depend on the widget’s BuildContext, as well as for any tasks that need to be performed once the widget is fully initialized and ready for interaction. Think of it as a way on performing tasks that cannot be done in the constructor of your class because they rely need to have access to the context. `initState is called after the constructor of the State class, so any data initialized in the constructor will already be available.While it’s possible to make intial network calls in the
initState
method, it’s generally not recommended to do it since it will imply that every time such widget is inserted in the tree that call will be performed.There is not an easy solution to your question. It seems you have a problem which involves the state-management of your app. I would recommend moving that network call to somewhere else which does not depend on your widgets tree (maybe to your "main()" function) but rather of the apps global state. Since you are performing asynchronous calls and interacting with network service, you cannot rely on simple app state management techniques. I would recommend to:
There is no correct choice for which state-management approach to used, but since you have already started Providers and ChangeNotifier, I would recommend upgrading to Riverpod.