I'm rebuilding an iOS app using Flutter and the flow is as followed: Everytime the user lands on the homepage, the user data is reloaded from the backend to check if anything has changed.
The way I achieve this in Swift / iOS is by using the viewDidLoad() function.
My Flutter code is like this:
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
User user = User();
@override
void dispose() {
super.dispose();
}
@override
void initState() {
super.initState();
_fetchData(context);
}
@override
Widget build(BuildContext context) {
return Container(
color: RColor.COLOR_main,
child: Column(
children: [
Container(
height: MediaQuery.of(context).size.height / 7,
width: MediaQuery.of(context).size.width,
padding: EdgeInsets.all(20),
child: Container(
child: Text("This is the homepage"),
alignment: Alignment.bottomCenter,
),
),
],
));
}
Future _fetchData(BuildContext context) async {
_fetchUserAPI(context);
}
Future _fetchUserAPI(BuildContext context) async {
try {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token");
var url = RConstants.API_BASE_URL + "/v1/users/self";
Response response = await Dio()
.get(url, options: Options(headers: {"Authorization": accessToken}));
setState(() {
user = User.fromJson(response.data);
});
} catch (e) {
print(e.toString());
Alert(
context: context,
title: "Something Went Wrong",
desc: "Something went wrong while fetching your user data",
type: AlertType.error)
.show();
}
}
}
void initState() however, doesn't get triggered each time the user lands on the homepage. What is the correct way to achieve this?
ViewDidLoad is called when the view is loaded in to memory. i.e if you are using storyboard, the app has unarchived the view and loaded it into memory(not yet on screen). When the app is ready to load the view on the screen it will call the viewWillAppear method.
viewWillAppear(_:)Always called after viewDidLoad (for obvious reasons, if you think about it), and just before the view appears on the screen to the user, viewWillAppear is called.
Well, it really depends on what exactly you mean by "Everytime the user lands on the homepage".
If user navigates from the HomePage
to some other view via Navigator.push
and then goes back via Navigator.pop
then the HomePage
's state remain the same and of course the initState
method does not trigger.
If you want to get notified on the HomePage
if the route above it in the navigator gets popped then you need to use this method, override it and then inside it you will be able to call the _fetchData()
and update the homepage's state.
One more thing: when you have some async call like _fetchData()
it is a wrong pattern to just invoke it inside the initState()
or any other framework methods. Because it will be invoked and the build()
method of your state will almost always be invoked immediately before the result of async call will come back. The correct way to handle such situations is to use the FutureBuilder widget.
If "Everytime the user lands on the homepage" means something else, like e.g. the app was in the background and gets brought foreground or when there is support for push notifications implemented and users click on the notification and the app is opened - such cases also can be handled but that is a broader topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With