3

I have a button in my screen and I am calling _fetchPost() whenever I click it. This method calls fetchPost(). I am able to see my parsed object when I set break point on var post = ... line. However, my problem is builder won't be called.

I am very new in Flutter, so is my code wrong?

void _fetchPost() {
    FutureBuilder<Post>(
      future: fetchPost(),
      builder: (BuildContext context, AsyncSnapshot<Post> snapshot) {
        if (snapshot.hasData) {
          String res = snapshot.data.parm1.toString() + snapshot.data.op + snapshot.data.parm2.toString();
          setState(() {
            _result = res;
          });
        } else if (snapshot.hasError) {
          setState(() {
            _result = snapshot.error;
          });
        }

        // By default, show a loading spinner
        return CircularProgressIndicator();
      },
    );
  }

  Future<Post> fetchPost() async {
    final response = await http.get('http://test.ethorstat.com/test.ashx');
    if (response.statusCode == 200) {
      // If server returns an OK response, parse the JSON
      var post = Post.fromJason(json.decode(response.body));
      return post;
    } else {
      // If that response was not OK, throw an error.
      throw Exception('Failed to load post!');
    }
  }
halfer
  • 19,824
  • 17
  • 99
  • 186
Hesam
  • 52,260
  • 74
  • 224
  • 365
  • Hi Hesam. I am a volunteer editor here, and one of the things that we like to do is to edit questions and answers for succinctness. In particular, niceties such as thanks, appreciations, salutations and signatures are not required in technical writing, and we discourage them. This has been discussed on Meta in this article: [Should I remove 'fluff' when editing questions?](https://meta.stackoverflow.com/questions/260776/should-i-remove-fluff-when-editing-questions) – halfer Aug 26 '18 at 22:32
  • @hesam Could you please help me on this same type question? https://stackoverflow.com/questions/64540805/why-futurebuilder-callback-is-not-calling-after-facebook-logged-in-data-in-flutt – Emon Oct 26 '20 at 16:47

1 Answers1

9

FutureBuilder is a widget. This means that in order for it to work, you need to insert it into the widget tree first.

Either you add your FutureBuilder to the widget tree by returning it as a child to another widget or directly to a build function of a widget:

class FetchWidget extends StatelessWidget {

  @override
  Widget build(BuildContext context) => FutureBuilder<Post>(
    future: fetchPost(),
    builder: (BuildContext context, AsyncSnapshot<Post> snapshot) {
      if (snapshot.hasData) {
        String res = snapshot.data.parm1.toString() + snapshot.data.op + snapshot.data.parm2.toString();
        setState(() { // setState will not work here, I only used this StatelessWidget to show what I mean with inserting it into the build tree
          _result = res;
        });
      } else if (snapshot.hasError) {
        setState(() {
          _result = snapshot.error;
        });
      }

      // By default, show a loading spinner
      return CircularProgressIndicator();
    },
  );

  Future<Post> fetchPost() async {
    final response = await http.get('http://test.ethorstat.com/test.ashx');
    if (response.statusCode == 200) {
      // If server returns an OK response, parse the JSON
     var post = Post.fromJason(json.decode(response.body));
     return post;
    } else {
      // If that response was not OK, throw an error.
     throw Exception('Failed to load post!');
    }
  }
}

This will not compile because I only copied your code into a StatelessWidget, which does not have setState. I only wanted to show what I mean by saying "add [...] to the widget tree".

Or you can just use regular async await for what you are trying to do:

void _fetchPost() async {
  final Post fetchedPost = await fetchPost();
  final String res = fetchedPost.parm1.toString() + fetchedPost.op + fetchedPost.parm2.toString();
  setState(() {
    _result = res;
  });
}

I am not sure how you want to implement your fetchPost, but if you want to use FutureBuilder, you need to insert it into the widget tree and return a widget to the builder.

creativecreatorormaybenot
  • 114,516
  • 58
  • 291
  • 402
  • Thanks. So, my underestanding was wrong. I thought I can use `FutureBuilder` just to download something from backend. – Hesam Jul 04 '18 at 07:04
  • A `FutureBuilder` is a way to process a `Future` in the wiget tree in a neat way. Awaiting a `Future` in a function will do. – creativecreatorormaybenot Jul 04 '18 at 07:09
  • @creativecreatorormaybenot Could you please help me on this same type question?? https://stackoverflow.com/questions/64540805/why-futurebuilder-callback-is-not-calling-after-facebook-logged-in-data-in-flutt – Emon Oct 26 '20 at 16:46