1

I'm making a mobile app in Flutter and this is keeping me from progressing for quite some time now, so I figured I'd ask StackOverflow!

I have a variable that is declared in a Future function, and what I essentially want to do is: check if the variable (which is an array) has been populated, if yes then display the results, if no then display a circular progress bar. I have most of the code done but, when it checks for the variable value it always says it's equal to zero, and it keeps displaying the circular progress bar forever! The only way to make the values appear is by using the "search" included in the app or not including this "if" at all!

Here is the code used for the function that initiates the _posts variable, it gets called when the app starts.

Future<void> fetchPosts([String tags]) async {
    var result;
    if (tags != null) {
      apiUrl += tags;
      result = await http.get(apiUrl);
      setState(() {});
    } else {
      result = await http.get(apiUrl);
      setState(() {});
    }
    _posts = json.decode(result.body);
  }

And this is the code for the Widget that displays everything.

Widget build(BuildContext context) {
    return Scaffold(
        appBar: _messageSelected
            ? _defaultBar(context, appBarChange)
            : _editingBar(context, appBarChange),
        body: Container(
            child: _posts.length != 0
                   ^^^^^^^^^^^^^^^^^^
                ? RefreshIndicator(
                    child: GridView.count(
                        crossAxisCount: 2,
                        children: List.generate(_posts.length, (index) {
                          return InkWell(
                              onTap: () {
                                Navigator.push(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) => DetailScreen(),
                                    settings: RouteSettings(
                                      arguments: _posts[index],
                                    ),
                                  ),
                                );
                              },
                              child: Image.network(
                                _url(_posts[index]),
                                width: 270,
                                height: 270,
                                fit: BoxFit.cover,
                              ));
                        })),
                    onRefresh: () {
                      return _getData();
                    })
                : Center(child: CircularProgressIndicator())));
  }

(I highlighted the part where it checks the variable, maybe there is a way to fit a "while" in there?)
How would I make it check the variable again here : Center(child: CircularProgressIndicator()))); and display the correct values?

I've been struggling with this for a while now, any help, suggestions or feedback would be appreciated! Thanks in advance.

SSudor
  • 87
  • 2
  • 9
  • 2
    Where did you call the `fetchPosts(...)`? Have you tried using FutureBuilder? https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html – rickimaru Jan 01 '21 at 10:03
  • @rickimaru ```fetchPosts()``` is called right when the app starts, and yes, FutureBuilder was what I needed! – SSudor Jan 07 '21 at 17:23

1 Answers1

2

Instead of calling setState directly within the function, You'll need to use a FutureBuilder for this, it'll listen for the changes in method passed down to future: parameter and then set the state accordingly.

In your case, to implement this you'll first need to modify the future method

Future fetchPosts([String tags]) async {
    var result;
    if (tags != null) {
      apiUrl += tags;
    }
    result = await http.get(apiUrl);
    _posts = json.decode(result.body);

   return Future.value(_posts);
  }

and then wrap your widgets with FutureBuilder

...

body:Container(
  child: FutureBuilder(
  future:fetchPosts(..args),
  builder:(BuildContext context, AsyncSnapshot snapshot){

       if(!snapshot.hasData) return CircularProgressIndicator();

       if(snapshot.hasError) return Text("Something went wrong");

       return YourScreenWidget()
    }
  )
)

you can read more on FutureBuilder in the flutter docs here

ishandeveloper
  • 176
  • 1
  • 7