简体   繁体   中英

Flutter: How to fetch data from api once and use for different screen

How can I fetch data, for example user detail once in one screen and use it in another screen?

I want to fetch the data once and I can use the data in another screen and no need to fetch again. Thank you.

您可以尝试使用共享首选项来存储数据并在每次要使用它时检索它

If I understand your question you know how to fetch user details, but don't want to load it several times, rather use the data from different widgets.

Shared preferences could work but I don't recommend it, it is meant to store only primitive data.

An easy but not perfect solution is to create an application level singleton-like class. You can load/update user details and it can be accessed from everywhere in your app. Something like:

class UserDetails {
   // define every member data here that you will load
   static late String name;
   static late String email;
   
   // this makes it singleton-like
   factory UserDetails() => UserDetails._internal();
   UserDetails._internal();
}

You can set / get user details like:

UserDetails.name

A more Flutter-like approach would be considering user details as a state of your app and use notifiers to "broadcast" these values throughout your widget tree. A good starting point would be to read this part in the documentation .

Here is a very simple example how to load the data from an API and store the data in the singleton class . The example is restricted to only one data (email) but of course you can extend it. In real world application a lot of error handling would be needed, this example assumes that everything is just fine:

class UserDetails {
  static late String email;

  factory UserDetails() => UserDetails._internal();
  UserDetails._internal();

  static Future<void> getUserDetails() async {
    // API_BASE_URL for example: "domain.com"
    // API_URL for example: "/user/details"
    // AUTHORIZATION: optional, skip headers part if you don't need
    final response = await http.get(
        Uri.https(API_BASE_URL, API_URL),
        headers: {'authorization': AUTHORIZATION});

    // here we decode the response body, assuming
    // that data is under "data" tag in response JSON
    final responseData = jsonDecode(response.body)["data"];

    // and within it we have an "email" tag with the user's mail
    // here 'email' is the static member of this class
    // and we set the value from the API response
    email = responseData["name"];
  }
}

Beware, for simplicity there is no error handling . We don't even check whether the response has a status code of 200. (You can easily add it, hint: response.statusCode contains it.) Furthermore, other things can go wrong, server outage etc.

Ok, so how to load the data and access it? The function getUserDetails is async, so somewhere in your code (somewhere early I guess) you have to call it once from another async function so you can await it. Make sure you find a place where it won't run again and check with debug console! The following line will get the data from the API and store it in the static member:

await UserDetails.getUserDetails();

If this is done, you can read and write the user details loaded from your API, from anywhere in your application, without reloading it:

print(UserDetails.email);
UserDetails.email = "new email";

Write your API function in other file see below:

Future apiCall() async {
  var url = 'put your API url here';
  var result = await http.get(url);
  if (result.statusCode == 200) {
    return json.decode(result.body);
  } else {
    throw Exception('Failed');
  }
}

then call your API function in other file when you call the API below:

FutureBuilder(
      future: apiCall(),
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          if (snapshot.data.length > 0) {
            return Text(
              
                  '${snapshot.data[0]['name']}'
                  
              style: TextStyle(
                fontWeight: FontWeight.bold,
                wordSpacing: 200,
                fontSize: 20,
              ),
             
            );
          } else {
            return Text(
              '❌ No Data Found',
              style: TextStyle(
                color: Colors.red,
              ),
            );
          }
        }
        return CircularProgressIndicator();
      },
    ),

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM