[FIXED] How to avoid CircularProgressIndicator when visiting screen next time?

Issue

I am creating a simple demo fetching json data.

I’ve used a Tab bar in my Homepage screen with 3 tabs: one for users, one for todos.

Everything is working well but when I want a little change…on tapping tab it’s showing a CircularProgressbar each and everything because I am fetching data with Future function and a FutureBuilder.

What I would like to achieve is: it should show the CircularProgressbar only the first time, then data should be copied into a local array so that the next time this local data will be shown to avoid loading with the CircularProgressIndicator.

Here is my code:

 Future<List<User>> getuserlist() async
  {
    List<User> userlist=[];
    final response=await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
    final jsondata=json.decode(response.body);
    userlist.clear();
    for(var data in jsondata)
      {
        userlist.add(User.fromJson(data));

      }
    return userlist;
  }

here is screen’s body code

FutureBuilder(
        future: getuserlist(),
        builder: (context,AsyncSnapshot snapshot){
          if(snapshot.connectionState==ConnectionState.waiting)
            {
              return Center(child: CircularProgressIndicator());
            }
          else
            {
              if(snapshot.connectionState==ConnectionState.active || snapshot.connectionState==ConnectionState.done)
                {
                  if(snapshot.hasData) {
                    return ListView.builder(
                        itemCount: snapshot.data.length,
                        itemBuilder: (context,index){
                          User user=snapshot.data[index];
                          return ListTile(
                            title: Text(user.name.toString()),
                            subtitle: Text(user.email.toString()),
                            leading: CircleAvatar(child: Text(user.id.toString()),),

                          );
                        });
                  }
                  else
                    {
                      if(snapshot.hasError)
                        {
                          return Text('Error found');
                        }
                      else
                        {

                          return Text('No error no data...');
                        }
                    }

                }
              else
                {
                  return Text('Something wrong');
                }


            }
        },
      ),

Solution

If you want cache data when user close and reopen the app, You can use shared_preferences, to cache the data like this:

Future<List<User>> getuserlist() async
  {
    List<User> userlist=[];
    List jsondata=[];
    final prefs = await SharedPreferences.getInstance();
    await prefs.reload();
    String responsePrefs = prefs.getString(key);

    if(responsePrefs != null){
      jsondata = json.decode(responsePrefs);
    }else {
      final response=await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
      final prefs = await SharedPreferences.getInstance();
      await prefs.reload();
      prefs.setString('response', response.body);
   
      jsondata = json.decode(response.body);

    }
    
    userlist.clear();
    for(var data in jsondata)
      {
        userlist.add(User.fromJson(data));

      }
    return userlist;
  }

But if you want cache data just for switching between pages, you can do this:

first create singleton class like this:

class GlobalVariable extends ChangeNotifier {
  static GlobalVariable? _instance;
  factory GlobalVariable() => _instance ??= new GlobalVariable._();
  GlobalVariable._();

  List<User> _users = [];

  setUsers(List<User> user) {
    _users = user;
  }

  List<User> getUsers() {
    return _users;
  }
}

then change your getuserlist() to this:

Future<List<User>> getuserlist() async
  {
    List<User> userlist=[];
    if(GlobalVariable().getUsers().isEmpty){
      final response=await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));
      final jsondata=json.decode(response.body);
      userlist.clear();
      for(var data in jsondata)
        {
          userlist.add(User.fromJson(data));

        }
      return userlist;
    }else{
      return GlobalVariable().getUsers();
    }
    
  }

Answered By – eamirho3ein

Answer Checked By – Candace Johnson (Easybugfix Volunteer)

Leave a Reply

(*) Required, Your email will not be published