Irfan Ganatra
Irfan Ganatra

Reputation: 1346

Appbar should show number of records using futurebuilder in flutter

I have just created a demo for better understanding future builder

scaffold body showing all users from api and appear should be shown with number of users

appear's title showing 0 when loaded but does not change...what to do to rebuild it

here is my code


class _withmodelState extends State<withmodel> {

  List<UserModel> userlist=[];

  Future<List<UserModel>> getdata() async {
    final resp =
        await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));

    if (resp.statusCode == 200) {
      print('i ma called');
      List<dynamic> dlist = json.decode(resp.body);
      await Future.delayed(Duration(seconds: 2));

      userlist= dlist.map((e) => UserModel.fromJson(e)).toList();
      return userlist;
    }
    return userlist;


  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
        child: Scaffold(
          appBar: AppBar(title: Text("Total users="+userlist.length.toString()),),
      body: MyBody(
        //MyBody returning FutureBuilder for showing userlist array;
      ),
    ));
  }

Upvotes: 0

Views: 181

Answers (2)

Souradeep
Souradeep

Reputation: 31

You also need to rebuild the Text widget, that you are using to show the count, when the count is available, i.e., the Future completes.

You need to wrap that Text widget with FutureBuilder like this:

return SafeArea(
  child: Scaffold(
    appBar: AppBar(
      title: FutureBuilder<List<UserModel>>(
        future: getdata(),
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            final List<UserModel> userlist = snapshot.data!;
            return Text("Total users= ${userlist.length}");
            // it's better to use String interpolation than "Total users=" + snapshot.data!.length.toString()
          } else {
            // return loading widget
          }
        },
      ),
    ),
    body: MyBody(
      //MyBody returning FutureBuilder for showing userlist array;
    ),
  ),
);

It is better to have the Future in a variable, and then use it like this, to avoid unwanted and repeated calling of it whenever the build() method is called:

late final Future<List<UserModel>> _userListFuture;

And initialize it in your initState(), like this:

@override
void initState() {
  super.initState();
  _userListFuture = Future<List<UserModel>>(getdata);
}

And use it with your FutureBuilder like this:

FutureBuilder<List<UserModel>>(
  future: _userListFuture,
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      // return your widget showing data
    } else {
      // return loading widget
    }
  },
)

Upvotes: 1

eamirho3ein
eamirho3ein

Reputation: 17900

You can use ChangeNotifier like this, first create a class like this:

class WithmodelDecl with ChangeNotifier {
  ValueNotifier<int> totalUsers = ValueNotifier<int>(0);
}

WithmodelDecl withmodeldecl = new WithmodelDecl();

then use it like this:

return SafeArea(
        child: Scaffold(
          appBar: PreferredSize(
          child: ValueListenableBuilder<int>(
              valueListenable: withmodeldecl.totalUsers,
              builder: (context, value, _) {
                return AppBar(
                  title: Text("Total users=" + value.toString()),
                );
              }),
          preferredSize: AppBar().preferredSize),
      body: MyBody(
        //MyBody returning FutureBuilder for showing userlist array;
      ),
));

and finally change your getdata to this:

Future<List<UserModel>> getdata() async {
    final resp =
        await http.get(Uri.parse('https://jsonplaceholder.typicode.com/users'));

    if (resp.statusCode == 200) {
      print('i ma called');
      List<dynamic> dlist = json.decode(resp.body);
      await Future.delayed(Duration(seconds: 2));

      userlist= dlist.map((e) => UserModel.fromJson(e)).toList();
      withmodeldecl.totalUsers.value = userlist.length;
      return userlist;
    }
    return userlist;


  }

Upvotes: 1

Related Questions