0

I'm trying to get the user's currency from my server. Until now I'm able to do that but the problem is the data keeps rebuild itself everytime the app gets rebuilt. I tried to fix that by this way :

  Future<dynamic> userDataFuture;

ApiService apiService;

 @override
 void initState() {
userDataFuture = apiService.getUserData();
super.initState();
}

but fails as it gives me an error saying :

The method 'getUserData' was called on null. Receiver: null Tried calling: getUserData()

this is my ApiService Class

  Future getUserData() async {
String token = await AuthProvider().getToken();
String userID = await AuthProvider().getUserId();

final response = await Dio().get(
  '$apiUrl/$userID',
  options: Options(headers: {
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'Authorization': 'Bearer $token',
  }),
);

if (response.statusCode == 200) {
  return response.data;
} else {
  throw Exception('Failed to load data');
}
}

this is my UI where I want to show the user's currency:

      child: Center(
                      child: FutureBuilder(
                        future: userDataFuture,
                        builder:
                            (BuildContext context, AsyncSnapshot snapshot) {
                          if (snapshot.hasError) {
                            return Center(
                              child: Text(
                                  "Something wrong with message: ${snapshot.error.toString()}"),
                            );
                          } else if (snapshot.connectionState ==
                              ConnectionState.done) {
                            return Text(
                                snapshot.data[
                                    'currency'], // This Should Change Depending in Settings of the User
                                style: TextStyle(
                                    fontSize:
                                        (device.localWidth * .1) * .43,
                                    fontWeight: FontWeight.w500,
                                    color: kLightTextColor));
                          } else {
                            return Center(
                              child: CircularProgressIndicator(),
                            );
                          }
                        },

                        // ),
                      ),
                    ),
  • Consider migrating to Flutter 2.0 and you will avoid this kind of errors – Abel Rodríguez May 24 '21 at 00:42
  • @Abel Rodriguez I assume you're referring to Dart null safety but FYI that's not related to Flutter 2.0. It's a separate thing and upgrading to 2.0 alone won't help here. Null safety (Dart min sdk 2.12) however is the default for new projects as of Flutter 2.2. – Loren.A May 24 '21 at 03:02
  • @Loren.A yes, I know and you are right. I should say that when you upgrade to Flutter 2.0 you also get Dart last version by default, which includes null safety. Therefore, many IDEs will hint you with an error when you try to access a function or property from a variable which is nullable like the case of this question. I mean, it will help using null safety to avoid such a problem with nullable variables. – Abel Rodríguez May 24 '21 at 05:18

2 Answers2

1

You're calling getUserData() on an ApiService object that is not initialized -- ie. null.

Instead of this

ApiService apiService;

Actually initialize it like this

final apiService = ApiService();

That will get rid of your null error. You can also just pass apiService.getUserData() into your FutureBuilder and get rid of the userDataFuture object altogether.

Loren.A
  • 4,872
  • 1
  • 10
  • 17
  • Ok, I got rid of that error but how could I stop the futureBuilder from reloading every time? – Shahad Alharbi May 24 '21 at 00:59
  • 1
    I guess that depends on whats happening in your app before the user navigates to that page. Try sharing the code that happens before you get to that screen. You could initialize the currency before hand and not use a `FutureBuilder` at all and just pass in data, for example. Or implement a state management solution that gives you more control over rebuilds. – Loren.A May 24 '21 at 03:08
0

first of all you have to use await, here like this

userDataFuture = await apiService.getUserData();

second you have to initialize you'r apiService variable like this:

ApiService apiService = new ApiService();

third, change you'r getUserData to return some data, it's void function.

fourth one you have to use somethink like this:

setState(() {
    userDateFuture = await apiService.getUserData();
});

i hope, i was able to help.