QuintessentialGamer
QuintessentialGamer

Reputation: 51

Populate List<Object> from database in initState()

I have a flutter app that kind of emulates Reddit. Users can create a Post(title, numdownvotes, numupvotes). Users can also see the posts in a DataTable and visualize the posts data with a flutter_chart. I already have it working with hardcoded values for the posts where there is a List that gets initialized with instances of Post inside it and then the DataTable and flutter_chart use this List to populate themselves. I'm now trying to add sqflite functionality to it and have made some progress. I can add posts to the database, and read them out to the console. I'm struggling with how I can initialize the List<Post?> posts to contain data from the database.

I tried doing it like such in the initState() but get an error: type 'Future' is not a subtype of type 'List?' in type cast

Here's my code: `

@override
void initState(){
  super.initState();
  _posts = model.getAllPosts() as List<Post>?;

  model.insertPost(Post(title: "Coolest Post", numDownVotes: 6, numUpVotes: 9));
  model.insertPost(Post(title: "Nice Post", numDownVotes: 8, numUpVotes: 10));
  model.insertPost(Post(title: "Dope Post", numDownVotes: 2, numUpVotes: 1));
}

`

The model in this case is a class I made that reads from the database: `

Future getAllPosts() async{
  //This needs to be present in any queries, updates, etc.
  //you do with your database
  final db = await DBUtils.init();
  final List maps = await db.query('post_items');
  List result = [];
  for (int i = 0; i < maps.length; i++){
    result.add(
        Post.fromMap(maps[i])
    );
  }
  return result;
}

`

I did some type checking to see what exactly is returned from getAllPosts() and it is a list of Post objects so I'm not being able to understand why my code in initState() does not work? Would be very helpful if someone could provide insight on how I can populate my variable _posts with data from the database.

Code for the DataTable. It uses _posts which is a hardcoded List<Post?>. The DataTable is within a Scaffold():

 body: DataTable(
    sortColumnIndex: sortColumnIndex,
    columns: [
      DataColumn(label: Text("Ttile"), onSort: onSort),
      DataColumn(label: Icon(Icons.arrow_drop_up), onSort: onSort),
      DataColumn(label: Icon(Icons.arrow_drop_down), onSort: onSort)
    ],
    rows:
      _posts!.map(
              (Post post) => DataRow(
                  cells: <DataCell>[
                    DataCell(Text(post.title!.toString())),
                    DataCell(Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Text(post.numUpVotes!.toString()),
                        IconButton(icon: Icon(Icons.arrow_upward), onPressed: () {
                          setState(() {
                            post.numUpVotes = (post.numUpVotes! + 1);
                          });
                        },
                        )
                      ],
                    )
                    ),
                    DataCell(Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Text(post.numDownVotes!.toString()),
                        IconButton(icon: Icon(Icons.arrow_downward), onPressed: () {
                          setState(() {
                            post.numDownVotes = post.numDownVotes! - 1;
                          });
                        },)
                      ],
                    )
                    )
                  ]
              )).toList(),

Upvotes: 0

Views: 192

Answers (1)

Gwhyyy
Gwhyyy

Reputation: 9166

first set a return type for your _ method:

    Future<List<Post>> getAllPosts() async{ // specify type
  //This needs to be present in any queries, updates, etc.
  //you do with your database
  final db = await DBUtils.init();
  final List maps = await db.query('post_items');
  List<Post> result = []; // specify type
  for (int i = 0; i < maps.length; i++){
    result.add(
        Post.fromMap(maps[i])
    );
  }
  return result;
}

then use this FutureBuilder widget in your UI:

FutureBuilder<List<Post>>(
        future: getAllPosts(),
        builder: (_, AsyncSnapshot<List<Post>> snapshot) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasData) {
            final _posts = snapshot.data! as List<Post>;
            print(_posts);

            return DataTable(
              sortColumnIndex: sortColumnIndex,
              columns: [
                DataColumn(label: Text("Ttile"), onSort: onSort),
                DataColumn(
                    label: Icon(Icons.arrow_drop_up), onSort: onSort),
                DataColumn(
                    label: Icon(Icons.arrow_drop_down), onSort: onSort)
              ],
              rows: _posts!
                  .map((Post post) => DataRow(cells: <DataCell>[
                        DataCell(Text(post.title!.toString())),
                        DataCell(Row(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Text(post.numUpVotes!.toString()),
                            IconButton(
                              icon: Icon(Icons.arrow_upward),
                              onPressed: () {
                                setState(() {
                                  post.numUpVotes = (post.numUpVotes! + 1);
                                });
                              },
                            )
                          ],
                        )),
                        DataCell(Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          crossAxisAlignment: CrossAxisAlignment.center,
                          children: [
                            Text(post.numDownVotes!.toString()),
                            IconButton(
                              icon: Icon(Icons.arrow_downward),
                              onPressed: () {
                                setState(() {
                                  post.numDownVotes =
                                      post.numDownVotes! - 1;
                                });
                              },
                            )
                          ],
                        ))
                      ]))
                  .toList(),
            );
          }

          return Text("no data");
        },
      ),

Upvotes: 1

Related Questions