Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

snapshot.ConnectionState always waiting

Tags:

flutter

dart

In a FutureBuilder, snapshot.ConnectionState is always waiting, but the future function completed successfully. While in a different page the same block of code works and the ConnectionState transitions from waiting to done.

The future function:

Future getDoctors() async {
    var res = await http.get(globals.domain + "users/docs/");
    var resBody = json.decode(utf8.decode(res.bodyBytes));

    print(res.statusCode);

    if (res.statusCode == 200) {
      if (mounted) {
        setState(() {
          doctors = resBody;
        });
      }
    }
  }

The future builder:

FutureBuilder(
    future: getDoctors(),
    builder: (BuildContext context, snapshot) {
        print(snapshot);
    }
)

Actual result: AsyncSnapshot<dynamic>(ConnectionState.waiting, null, null) Expected result: transiton to AsyncSnapshot<dynamic>(ConnectionState.done, null, null)

EDIT1: while debugging noticed that the future function getDoctors() is called periodically, I guess that's why the snapshot is always waiting

like image 918
Omar Ahmad Avatar asked Feb 15 '19 13:02

Omar Ahmad


People also ask

What is ConnectionState active?

ConnectionState. active: It means the future is not null but it is not resolved yet.

What is flutter AsyncSnapshot?

AsyncSnapshot<T> class Null safety. Immutable representation of the most recent interaction with an asynchronous computation. See also: StreamBuilder, which builds itself based on a snapshot from interacting with a Stream. FutureBuilder, which builds itself based on a snapshot from interacting with a Future.

What is snapshot flutter?

Snapshot is the result of the Future or Stream you are listening to in your FutureBuilder . Before interacting with the data being returned and using it in your builder, you have to access it first.


1 Answers

Calling setState causes the widget tree to be rebuild. Therefore, when the FutureBuilder is rebuilt, the getDoctors() function is invoked again, causing an infinite loop (getDoctors()->setState()->rebuild->getDoctors()...)

The solution is to either remove setState from the getDoctors method or invoke getDoctors() once in the initState() method, store the Future and pass it to the FutureBuilder, thus ensuring that it is only done once.

Future _doctorsFuture;

initState() {
    ...
    _doctorsFuture = getDoctors();
}

.
.

// Somewhere in build()
    FutureBuilder(
        future: doctorsFuture,
        builder: (BuildContext context, snapshot) {
            print(snapshot);
        }
    ),
like image 152
Omar Ahmad Avatar answered Sep 22 '22 02:09

Omar Ahmad