Padam Ghimire
Padam Ghimire

Reputation: 11

Flutter FutureBuilder snapshot.data receiving null

I am trying to get data from sqflite using FutureBuilder Here is my Code :

Function To get charts from Sqflite

getCharts(table, column_name, ids) async {
   var conn = await database;
   // var li = [];
   var data = await conn.query(table,
       where: "indicator_id IN (${List.filled(ids.length, '?').join(',')})",
       whereArgs: ids);


   return data;
 } 

This Function Returns:

[
 {
   id: 1, indicator_id: 1, 
   label: Percentage of population with access to electricity,
   np: 89.9, 
   p1: 88.5,
   p2: 96.3,
   p3: 97.4, 
   p4: 98.9,
   p5: 90.8,
   p6: 44.9,
   p7: 77.1,
   chart_type: pie_chart, 
   name: Access to electricity,
   description: Percentage of population with access to electricity
  }
]

Function from Chart Service

Future<List<Chart>> getCharts(List<int> ids) async {
    var res = await _repository!.getCharts('charts', 'indicator_id', ids);

    var mapped = res.map((chart) => new Chart.fromJson(chart)).toList();
    print(mapped);

    return mapped;
  }

This Function Returns:

[Instance of 'Chart']

On The Chart Screen

 ChartService _chart2service = ChartService();
Future<List<Chart>>? futureChart;
  @override
  void initState() {
    super.initState();

    futureChart = _chart2service.getCharts(this.widget.ids!);
  }

But When I try FutureBuilder:

 FutureBuilder<List<Chart>>(
            future: futureChart,
            builder: (context, snapshot) {
            print(snapshot.data);
             })

snapshot.data is returning null value.

Upvotes: 1

Views: 1534

Answers (3)

Ravindra S. Patil
Ravindra S. Patil

Reputation: 14885

First think you check your getChart() function that have data present or not like :

var mapped = res.map((chart) => new Chart.fromJson(chart)).toList();
  print(mapped);
  return mapped;

If your function return mapped or console print the mapped your data come successful.

Then you create Widget using FutureBuilder like below:

FutureBuilder<List<Chart>>(
                  future: futureChart(),
                  builder: (context, snapshot) {
                    if (snapshot.hasData) { 
                return Text('Your Data : ${snapshot.data}');
          } else{ 
            return CircularProgressIndicator();
         }
       } 
   ),

Upvotes: 1

venir
venir

Reputation: 2096

I might be offering a "stupid" answer, but the body of the builder function just directly prints snapshot.data.

When the Future is launched, by definition, it has not yet completed. You must first check its status: is it uncompleted? Is it done, or are there errors (e.g. connection lost)?

Here's some example code:

class MyApp extends StatelessWidget {
  final futureChart = Future.delayed(Duration(seconds: 5));
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: Scaffold(
          body: Center(
            child: FutureBuilder(
                future: futureChart,
                builder: (context, snapshot) {
                  if (snapshot.hasError) {
                    // some logic... and the following UI:
                    return Container(child: Text("Woops!"));
                  }                   else if(snapshot.connectionState != ConnectionState.done) {
                    // some logic... and the following UI:
                    return Container(child: Text("Waiting..."));
                  }
                  
                  // we're finally done, we can add logic and some UI
                  return Container(child: Text("our future is done: ${snapshot.data}"));
                }),
          ),
        ),
      );
}

Upvotes: 2

Tirth Patel
Tirth Patel

Reputation: 5746

Check whether snapshot.data is null or not. FutureBuilder would provide the result when it's ready.

FutureBuilder<List<Chart>>(
  future: futureChart,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      print(snapshot.data);
      return Text('Data Loaded');
    }
    return Text('Loading Data...');
  },
);

Upvotes: 0

Related Questions