0

I want to create a listView in FutureBuilder. It's a List of Json Object, when i call the api, i receive the multiples objects but when i want created the list, I have differents errors.

For exemples :

A build function returned null. User-created ancestor of the error-causing widget was Expanded

Image : bug

Theme model:

class Theme {

  int id;
  String name;

  Theme({this.id, this.name});

  factory Theme.fromJson(Map<String, dynamic> json) {
    return Theme(
      id: json['id'],
      name: json['name'],
    );
  }

  Future<List<Theme>> getThemes() async {
  String url = 'http://10.0.2.2:3000/v1/api/theme';
  final response = await http.get(url, headers: {"Accept": "application/json"});

  if (response.statusCode == 200) {
    List themesList = jsonDecode(response.body);
    List<Theme> themes = [];
    for(var themeMap in themesList){
      themes.add(Theme.fromJson(themeMap));
    }
    return themes;
  } else {
    throw Exception('Failed to load themes');
  }
}

}

Theme page :

class _Theme extends State<Theme> {
  var name;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Blackbox"),
        ),
        body: new Center(
          child : new Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              new Container(
                margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
                child: new Text('Sélection du profil',
                    style: new TextStyle(
                        fontSize: 24, fontWeight: FontWeight.bold)),
                        alignment: Alignment.topCenter),
              new Expanded(
                child : new FutureBuilder<List<t.Theme>>(
                    future: t.Theme().getThemes(),
                    builder: (context, snapshot){
                      if (!snapshot.hasData){
                        return CircularProgressIndicator();
                      }else if(snapshot.hasError){
                        return Text("${snapshot.error}");
                      }else{
                        new ListView.builder(
                          itemCount: snapshot.data.length,
                          itemBuilder: (BuildContext context, index) {
                            for (var s in snapshot.data){
                              name = s.name;
                            }
                            return new ListTile(
                              title: new Text(name),
                            );
                          },
                        );
                      }                   
                    },
              )
              ),
              new Container(
              margin: EdgeInsets.only(right: 10.0),
              child: new RaisedButton.icon(
                /*onPressed: () {
                  Navigator.pushReplacement(context,
                      MaterialPageRoute(builder: (context) => Technologies()));
                },*/
                label: Text('Suivant'),
                icon: Icon(Icons.navigate_next),
              ),
              alignment: Alignment.bottomRight,
            ),
            ],
          ),
        ),
    );
  }
}
5
  • why your builder returns return name;? what kind of Widget is name variable? Commented Sep 18, 2019 at 9:11
  • I didn't attention, i delete this. But why my program, pass by else condition and don't print the list. Commented Sep 18, 2019 at 9:15
  • isnt FutureBuilder<List<t.Theme> t null here? Commented Sep 18, 2019 at 9:21
  • @pskink When i start the debug program, i have my 3 json items, snapshot.length = 3, so I don't know.. Commented Sep 18, 2019 at 9:23
  • @PeterHaddad when i test snapshot.data, i have : [Instance of 'Theme', Instance of 'Theme', Instance of 'Theme'] Commented Sep 18, 2019 at 9:34

1 Answer 1

1

It is because you have missed return before new ListView.builder in FutureBuilder's builder method, so it is not returning anything but null.

So, your updated Theme page will like this:

  class _Theme extends State<Theme> {
     var name;
     @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("Blackbox"),
        ),
        body: new Center(
          child : new Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: <Widget>[
              new Container(
                margin: EdgeInsets.only(top: 10.0, bottom: 10.0),
                child: new Text('Sélection du profil',
                    style: new TextStyle(
                        fontSize: 24, fontWeight: FontWeight.bold)),
                        alignment: Alignment.topCenter),
              new Expanded(
                child : new FutureBuilder<List<t.Theme>>(
                    future: t.Theme().getThemes(),
                    builder: (context, snapshot){
                      if (!snapshot.hasData){
                        return CircularProgressIndicator();
                      }else if(snapshot.hasError){
                        return Text("${snapshot.error}");
                      }else{
                        return ListView.builder(
                          itemCount: snapshot.data.length,
                          itemBuilder: (BuildContext context, index) {
                            for (var s in snapshot.data){
                              name = s.name;
                            }
                            return new ListTile(
                              title: new Text(name),
                            );
                          },
                        );
                      }                   
                    },
              )
              ),
              new Container(
              margin: EdgeInsets.only(right: 10.0),
              child: new RaisedButton.icon(
                /*onPressed: () {
                  Navigator.pushReplacement(context,
                      MaterialPageRoute(builder: (context) => Technologies()));
                },*/
                label: Text('Suivant'),
                icon: Icon(Icons.navigate_next),
              ),
              alignment: Alignment.bottomRight,
            ),
            ],
          ),
        ),
    );
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.