Stuck during initialization of List and Datasource

I'm following the video tutorial on using SfDataGrid in a Flutter app. As the tutorial's data was a predefined list, I tried my hand at modifying it so that the app reads a CSV file in the assets folder instead of the predefined list. As a result, I used the rootBundle.loadString function to read the file. And here is where I get stuck. 

Following the tutorial, I'm supposed to initialize the list and the datasource like so:

@override
void initState() {
    _regions = getRegionData();
    _regionDataSource = RegionDataSource(_regions);
  super.initState();
}

Unfortunately, as the file is being read by an async function (in getRegionData), I couldn't place it in initState. So I tried a couple of workarounds to use async in initState. Using this code:

@override
void initState() {
    getdata();
    _regionDataSource = RegionDataSource(_regions);
  super.initState();
}

void getData() async {
_regions = await getRegionData(); }

I get the error LateInitializationError: Field '_regions' has not been initialized. Same as when I use this code:

@override
void initState() {
  Future.delayed(Duration.zero, () async {
_regions = await getRegionData();
}
_regionDataSource = RegionDataSource(_regions);
super.initState();
}

But if I place the _regionDataSource initialization code within the Future.delayed block after initializing _regions, I get this error instead:  LateInitializationError: Field '_regionDataSource' has not been initialized.
Any tips on I can move on with this? And will it be the same if the _regions variable is initialized by a call to a database in the cloud?

Thank you!




1 Reply

TP Tamilarasan Paranthaman Syncfusion Team February 19, 2024 01:45 PM UTC

Hi,

As per your requirement, you can utilize the FutureBuilder widget to accomplish this task. Initially, initialize the `_regions` list as empty. Within the `FutureBuilder.future` property, invoke an asynchronous function to fetch the `_regions` data. Additionally, while awaiting the data retrieval, you can display a loading widget. Once the data is fetched, proceed to construct the DataGrid widget using the retrieved data. Below is an example code snippet illustrating this approach:


@override

void initState() {

  super.initState();

    _regions = []; // Empty List

}

 

  Future generateProductList() async {

    _regions = await http.get(Uri.parse(

        'https://ej2services.syncfusion.com/production/web-services/api/Orders')); 

    return Future.value(_regions);

  }

 

@override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: const Text('Syncfusion Flutter DataGrid'),

      ),

      body: FutureBuilder(

        future: generateProductList(),

        builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {

          if (snapshot.hasData) {

 

            _regionDataSource = RegionDataSource(_regions);

 

            return LayoutBuilder(builder: (context, constraints) {

              return SfDataGrid(

                           source: _regionDataSource,
                           columns: getColumns

            });

          } else {

            return const Center(child: CircularProgressIndicator());

          }

        },

      ),

    );

  }

 


We hope that this helps you. In case there's any misunderstanding regarding your requirement or if your requirements differ, we kindly request you to provide more specific and clear details about your use case. This additional information will assist us in thoroughly examining your request and delivering an appropriate solution.


Regards,

Tamilarasan


Loader.
Up arrow icon