---
title: "How to Perform Lazy Loading in Flutter Data Table"
published_at: "2021-05-19T10:00:17+00:00"
modified_at: "2026-02-10T08:38:43+00:00"
url: "https://www.syncfusion.com/blogs/post/lazy-loading-in-flutter-data-table"
excerpt: "In this blog post, we will see the steps to lazy load data in the Syncfusion Flutter DataGrid (data table) while fetching data from Firebase."
taxonomy_category:
  - "DataGrid"
  - "Desktop"
  - "Flutter"
taxonomy_post_tag:
  - "Android"
  - "Data Grid"
  - "desktop"
  - "Flutter"
  - "iOS"
---

# How to Perform Lazy Loading in Flutter Data Table

[Balasubramani Sundaram](https://www.syncfusion.com/blogs/author/balasubramani-sundaram)

![How to Perform Lazy Loading in Flutter DataGrid](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/How-to-Perform-Lazy-Loading-in-Flutter-DataGrid.png)


The Syncfusion [Flutter DataGrid (data table)](https://www.syncfusion.com/flutter-widgets/flutter-datagrid)
 widget provides support to load data lazily with an interactive view when the grid reaches its maximum offset while scrolling down. In this blog, we are going to discuss how to enable the load-more feature in Flutter DataGrid and perform the lazy loading of data fetched from [Firebase](https://firebase.google.com/)
. Before getting into the steps, go through the overview of [connecting Firebase to your Flutter application](https://firebase.flutter.dev/docs/overview/)
.

**Note:** In this blog, we use Firebase data as an example only. We are not going to provide the Firebase connectivity files here.

## **Dependency package**

Include the Syncfusion Flutter DataGrid and Firebase package dependencies in the **pubspec.yaml** file of your project using the following code.

```
firebase_core: ^1.0.2
cloud_firestore: ^1.0.3
syncfusion_flutter_datagrid: ^19.1.54-beta.1
```

## **Create a model data class**

Create an employee class to cast and store the Firebase data in your project.

Refer to the following code example.

```
import 'package:cloud_firestore/cloud_firestore.dart';

class Employee {
  Employee(this.employeeID, this.employeeName, this.designation,
      this.salary,
      {this.reference});

  double employeeID;

  String employeeName;

  String designation;

  double salary;

  DocumentReference? reference;

  factory Employee.fromSnapshot(DocumentSnapshot snapshot) {
    Employee newEmployee = Employee.fromJson(snapshot.data()!);
    newEmployee.reference = snapshot.reference;
    return newEmployee;
  }

  factory Employee.fromJson(Map<String, dynamic> json) =>
      _employeeFromJson(json);

  Map<String, dynamic> toJson() => _employeeToJson(this);

  @override
  String toString() => 'employeeName $employeeName';
}

Employee _employeeFromJson(Map<String, dynamic> data) {
  return Employee(
    data['employeeID'],
    data['employeeName'],
    data['designation'],
    data['salary'],
  );
}

Map<String, dynamic> _employeeToJson(Employee instance) {
  return {
    'employeeID' : instance.employeeID,
    'employeeName': instance.employeeName,
    'designation': instance.designation,
    'salary': instance.salary,
  };
}
```

## **Create a DataGridSource class and initialize the Firebase**

Please follow these steps to create a DataGridSource and initialize the Firebase:

### **Step 1: Create DataGridSource**

First, create a [DataGridSource](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/DataGridSource-class.html)
 class, which is required for the SfDataGrid. With this class, we are going to obtain the row data.

```
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

import '../model/employee.dart';

class EmployeeDataGridSource extends DataGridSource {
 
  List<DataGridRow> dataGridRows = [];

  List<Employee> employees = [];

  @override
  List<DataGridRow> get rows => dataGridRows;

  @override
  DataGridRowAdapter? buildRow(DataGridRow row) {
    return DataGridRowAdapter(
        cells: row.getCells().map<Widget>((dataGridCell) {
      if (dataGridCell.columnName == 'employeeID' ||
          dataGridCell.columnName == 'salary') {
        return Container(
          alignment: Alignment.centerRight,
          padding: EdgeInsets.symmetric(horizontal: 16.0),
          child: Text(
              (dataGridCell.columnName == 'salary') ? NumberFormat.currency(locale: 'en_US', symbol: '\
```

### **Step 2: Initialize Firebase**

Then, we have to initialize Firebase in the main() method to access the Firebase services.

```
import 'package:firebase_core/firebase_core.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(SfDataGridLoadMoreApp());
}
```

### **Step 3: Fetch data from cloud**

Now, initialize the Firebase collection inside the DataGridSource class to fetch data from the cloud.

```
import 'package:cloud_firestore/cloud_firestore.dart';

class EmployeeDataGridSource extends DataGridSource {
  EmployeeDataGridSource() {
    collection = FirebaseFirestore.instance.collection('employees');
  }

  late CollectionReference collection;
}
```

## **Enable the lazy-loading feature in DataGrid**

Now, let’s enable the lazy-loading feature in the Flutter DataGrid:

### **Step 1: Import packages**

First, import the Flutter DataGrid and Firebase repository packages in the main.dart file using the following code.

```
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_datagrid_loadmore/repositories/employee_repository.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';
```

### **Step 2: Implement lazy loading**

We can perform lazy loading by using either of the following ways in the Flutter data table:

- [Infinite loading](https://help.syncfusion.com/flutter/datagrid/load-more#infinite-scrolling)
- [LoadMore button](https://help.syncfusion.com/flutter/datagrid/load-more#load-more-button)

In this blog, we are going to lazy load data using the infinite-scrolling feature in the DataGrid:

- Use the [loadMoreViewBuilder](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/loadMoreViewBuilder.html) callback, which will be called when the DataGrid reaches its maximum vertical offset.
- In the loadMoreViewBuilder callback, provide the [loadMoreRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/LoadMoreRows.html) callback as a parameter.
- Using the loadMoreRows callback, you can load data lazily.

Refer to the following code example.

```
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_datagrid_loadmore/repositories/employee_repository.dart';
import 'package:syncfusion_flutter_datagrid/datagrid.dart';

class SfDataGridLoadMoreApp extends StatelessWidget {
  final EmployeeDataGridSource employeeDataGridSource =
      EmployeeDataGridSource();

  SfDataGridLoadMoreApp() {
    employeeDataGridSource.loadMoreStream();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('DataGrid Lazy Loading'),
        ),
        body: SfDataGrid(
          source: employeeDataGridSource,
          columnWidthMode: ColumnWidthMode.fill,
          columns: [
            GridTextColumn(
                columnName: 'employeeID',
                label: Container(
                  padding: EdgeInsets.symmetric(horizontal: 16.0),
                  child: Text(
                    'ID',
                    overflow: TextOverflow.ellipsis,
                  ),
                  alignment: Alignment.centerRight,
                )),
            GridTextColumn(
                columnName: 'employeeName',
                label: Container(
                    padding: EdgeInsets.symmetric(horizontal: 16.0),
                    child: Text(
                      'Name',
                      overflow: TextOverflow.ellipsis,
                    ),
                    alignment: Alignment.centerLeft)),
            GridTextColumn(
                columnName: 'designation',
                label: Container(
                    padding: EdgeInsets.symmetric(horizontal: 16.0),
                    child: Text(
                      'Role',
                      overflow: TextOverflow.ellipsis,
                    ),
                    alignment: Alignment.centerLeft)),
            GridTextColumn(
                columnName: 'salary',
                label: Container(
                    padding: EdgeInsets.symmetric(horizontal: 16.0),
                    child: Text(
                      'Salary',
                      overflow: TextOverflow.ellipsis,
                    ),
                    alignment: Alignment.centerRight)),
          ],
          loadMoreViewBuilder: loadMoreInfiniteBuilder,
        ),
      ),
    );
  }

  /// Hook this builder for applying the infinite scrolling support
  Widget loadMoreInfiniteBuilder(
      BuildContext context, LoadMoreRows loadMoreRows) {
    Future<String> loadRows() async {
      await loadMoreRows();
      return Future<String>.value('Completed');
    }

    return FutureBuilder<String>(
        initialData: 'loading',
        future: loadRows(),
        builder: (context, snapShot) {
          if (snapShot.data == 'loading') {
            return Container(
                height: 60.0,
                width: double.infinity,
                decoration: BoxDecoration(
                    color: Colors.white,
                    border: BorderDirectional(
                        top: BorderSide(
                            width: 1.0, color: Color.fromRGBO(0, 0, 0, 0.26)))),
                alignment: Alignment.center,
                child: CircularProgressIndicator(
                    valueColor: AlwaysStoppedAnimation(Colors.deepPurple)));
          } else {
            return SizedBox.fromSize(size: Size.zero);
          }
        });
  }
}
```

### **Step 3: Implement busy indicator**

- Then, override the handleLoadMoreRows property in the DataGridSource class to load more data lazily. This method will be called whenever the [loadMoreRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/LoadMoreRows.html) callback is called from the [loadMoreViewBuilder](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/loadMoreViewBuilder.html) callback.
- You can use **await** to show a busy indicator while fetching data from Firebase. Here, we have delayed ** 500 ms** manually to show the busy indicator for example purposes.

Refer to the following code example.

```
class EmployeeDataGridSource extends DataGridSource {

  static const double perPage = 100;

  List<Employee> employees = [];

  void addDataGridRow(Employee data) {
    dataGridRows.add(DataGridRow(cells: [
      DataGridCell<double>(columnName: 'employeeID', value: data.employeeID),
      DataGridCell<String>(
          columnName: 'employeeName', value: data.employeeName),
      DataGridCell<String>(columnName: 'designation', value: data.designation),
      DataGridCell<double>(columnName: 'salary', value: data.salary),
    ]));
  }

  Future loadMoreDataFromStream() async {
    final stream = collection
        .where('employeeID',
            isGreaterThan:
                employees.isEmpty ? 1000.0 : employees.last.employeeID,
            isLessThan: employees.isEmpty
                ? 1000.0 + perPage
                : employees.last.employeeID + perPage)
        .snapshots();

    stream.listen((snapShot) async {
      await Future.forEach(snapShot.docs, (DocumentSnapshot element) {
        final Employee data = Employee.fromSnapshot(element);
        if (!employees
            .any((element) => element.employeeID == data.employeeID)) {
          employees.add(data);
          addDataGridRow(data);
        }
      });

      updateDataGridDataSource();
    });
  }

  @override
  Future<void> handleLoadMoreRows() async {
    /// Perform delay to load the data to show the loading indicator if required.
    await Future.delayed(const Duration(milliseconds: 500), () {
      loadMoreDataFromStream();
    });
  }

  void updateDataGridDataSource() {
    notifyListeners();
  }
}
```

![Lazy Loading in Flutter DataGrid via Infinite Scrolling](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Lazy-Loading-in-Flutter-DataGrid-via-Infinite-Scrolling.gif)

Lazy Loading in Flutter Data Table via Infinite Scrolling

![Lazy Loading in Flutter DataGrid Using Load More Button](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Lazy-Loading-in-Flutter-DataGrid-Using-Load-More-Button.gif)

Lazy Loading in Flutter Data Table Using Load More Button

## **Resource**

For more information, refer to [Perform lazy loading in Flutter Data Table (SfDataGrid) demo](https://github.com/SyncfusionExamples/how-to-perform-lazy-loading-in-Flutter-DataTable-in-just-3-steps)
.

## **Conclusion**

In this blog post, we have seen the steps to lazy load data in the Syncfusion [Flutter DataGrid (data table)](https://www.syncfusion.com/flutter-widgets/flutter-datagrid)
 while fetching data from Firebase. With this, you can load only the required data at once and load the remaining data on demand. This will enhance your productivity and reduce the loading time, too.

Syncfusion DataGrid is also available in our [Blazor](https://www.syncfusion.com/blazor-components/blazor-datagrid)
, ASP.NET ([Core](https://www.syncfusion.com/aspnet-core-ui-controls/grid)
, [MVC](https://www.syncfusion.com/aspnet-mvc-ui-controls/grid)
, [WebForms](https://www.syncfusion.com/jquery/aspnet-web-forms-ui-controls/datagrid)
), [Angular](https://www.syncfusion.com/angular-ui-components/angular-grid)
, [React](https://www.syncfusion.com/react-ui-components/react-data-grid)
, [Vue](https://www.syncfusion.com/vue-ui-components/vue-grid)
, [Xamarin](https://www.syncfusion.com/xamarin-ui-controls/xamarin-datagrid)
, [Flutter](https://www.syncfusion.com/flutter-widgets/flutter-datagrid)
, [UWP](https://www.syncfusion.com/uwp-ui-controls/datagrid)
, [WinForms](https://www.syncfusion.com/winforms-ui-controls/datagrid)
, [WPF](https://www.syncfusion.com/wpf-ui-controls/datagrid)
, and [WinUI](https://www.syncfusion.com/winui-controls/datagrid)
 platforms. Use them to build powerful applications!

For existing customers, the new version is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads)
 page. If you are not yet a Syncfusion customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads)
 to check out our available features. Also, try our samples from this [GitHub](https://github.com/syncfusion)
 location.

You can contact us through our [support forum](https://www.syncfusion.com/forums)
, [Direct-Trac](https://www.syncfusion.com/support/directtrac/incidents)
, or [feedback portal](https://www.syncfusion.com/feedback/flutter)
. We are always happy to assist you!

## **Related blogs**

- [What’s New in 2021 Volume 1: Flutter](https://www.syncfusion.com/blogs/post/whats-new-in-2021-volume-1-flutter.aspx)
- [Introducing the New Flutter Treemap Widget](https://www.syncfusion.com/blogs/post/introducing-the-new-flutter-treemap-widget.aspx)
- [API Breaking Changes in Flutter DataGrid in 2021 Volume 1](https://www.syncfusion.com/blogs/post/api-breaking-changes-in-flutter-datagrid-in-2021-volume-1.aspx)
- [How to Sort Data in Syncfusion Flutter Data Tables Based on Multiple Columns](https://www.syncfusion.com/blogs/post/how-to-sort-data-in-syncfusion-flutter-data-tables-based-on-multiple-columns.aspx)

).format(dataGridCell.value).toString() :  
 dataGridCell.value.toInt().toString(),  
 overflow: TextOverflow.ellipsis,  
 ),  
 );  
 }  
 return Container(  
 alignment: Alignment.centerLeft,  
 padding: EdgeInsets.symmetric(horizontal: 16.0),  
 child: Text(dataGridCell.value.toString(),  
 overflow: TextOverflow.ellipsis),  
 );  
 }).toList());  
 }

void updateDataGridDataSource() {  
 notifyListeners();  
 }  
 }

### **Step 2: Initialize Firebase**

Then, we have to initialize Firebase in the main() method to access the Firebase services.

### **Step 3: Fetch data from cloud**

Now, initialize the Firebase collection inside the DataGridSource class to fetch data from the cloud.

## **Enable the lazy-loading feature in DataGrid**

Now, let’s enable the lazy-loading feature in the Flutter DataGrid:

### **Step 1: Import packages**

First, import the Flutter DataGrid and Firebase repository packages in the main.dart file using the following code.

### **Step 2: Implement lazy loading**

We can perform lazy loading by using either of the following ways in the Flutter data table:

- [Infinite loading](https://help.syncfusion.com/flutter/datagrid/load-more#infinite-scrolling)
- [LoadMore button](https://help.syncfusion.com/flutter/datagrid/load-more#load-more-button)

In this blog, we are going to lazy load data using the infinite-scrolling feature in the DataGrid:

- Use the [loadMoreViewBuilder](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/loadMoreViewBuilder.html) callback, which will be called when the DataGrid reaches its maximum vertical offset.
- In the loadMoreViewBuilder callback, provide the [loadMoreRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/LoadMoreRows.html) callback as a parameter.
- Using the loadMoreRows callback, you can load data lazily.

Refer to the following code example.

### **Step 3: Implement busy indicator**

- Then, override the handleLoadMoreRows property in the DataGridSource class to load more data lazily. This method will be called whenever the [loadMoreRows](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/LoadMoreRows.html) callback is called from the [loadMoreViewBuilder](https://pub.dev/documentation/syncfusion_flutter_datagrid/latest/datagrid/SfDataGrid/loadMoreViewBuilder.html) callback.
- You can use **await** to show a busy indicator while fetching data from Firebase. Here, we have delayed ** 500 ms** manually to show the busy indicator for example purposes.

Refer to the following code example.

![Lazy Loading in Flutter DataGrid via Infinite Scrolling](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Lazy-Loading-in-Flutter-DataGrid-via-Infinite-Scrolling.gif)

Lazy Loading in Flutter Data Table via Infinite Scrolling

![Lazy Loading in Flutter DataGrid Using Load More Button](https://www.syncfusion.com/blogs/wp-content/uploads/2021/05/Lazy-Loading-in-Flutter-DataGrid-Using-Load-More-Button.gif)

Lazy Loading in Flutter Data Table Using Load More Button

## **Resource**

For more information, refer to [Perform lazy loading in Flutter Data Table (SfDataGrid) demo](https://github.com/SyncfusionExamples/how-to-perform-lazy-loading-in-Flutter-DataTable-in-just-3-steps)
.

## **Conclusion**

In this blog post, we have seen the steps to lazy load data in the Syncfusion [Flutter DataGrid (data table)](https://www.syncfusion.com/flutter-widgets/flutter-datagrid)
 while fetching data from Firebase. With this, you can load only the required data at once and load the remaining data on demand. This will enhance your productivity and reduce the loading time, too.

Syncfusion DataGrid is also available in our [Blazor](https://www.syncfusion.com/blazor-components/blazor-datagrid)
, ASP.NET ([Core](https://www.syncfusion.com/aspnet-core-ui-controls/grid)
, [MVC](https://www.syncfusion.com/aspnet-mvc-ui-controls/grid)
, [WebForms](https://www.syncfusion.com/jquery/aspnet-web-forms-ui-controls/datagrid)
), [Angular](https://www.syncfusion.com/angular-ui-components/angular-grid)
, [React](https://www.syncfusion.com/react-ui-components/react-data-grid)
, [Vue](https://www.syncfusion.com/vue-ui-components/vue-grid)
, [Xamarin](https://www.syncfusion.com/xamarin-ui-controls/xamarin-datagrid)
, [Flutter](https://www.syncfusion.com/flutter-widgets/flutter-datagrid)
, [UWP](https://www.syncfusion.com/uwp-ui-controls/datagrid)
, [WinForms](https://www.syncfusion.com/winforms-ui-controls/datagrid)
, [WPF](https://www.syncfusion.com/wpf-ui-controls/datagrid)
, and [WinUI](https://www.syncfusion.com/winui-controls/datagrid)
 platforms. Use them to build powerful applications!

For existing customers, the new version is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads)
 page. If you are not yet a Syncfusion customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads)
 to check out our available features. Also, try our samples from this [GitHub](https://github.com/syncfusion)
 location.

You can contact us through our [support forum](https://www.syncfusion.com/forums)
, [Direct-Trac](https://www.syncfusion.com/support/directtrac/incidents)
, or [feedback portal](https://www.syncfusion.com/feedback/flutter)
. We are always happy to assist you!

## **Related blogs**

- [What’s New in 2021 Volume 1: Flutter](https://www.syncfusion.com/blogs/post/whats-new-in-2021-volume-1-flutter.aspx)
- [Introducing the New Flutter Treemap Widget](https://www.syncfusion.com/blogs/post/introducing-the-new-flutter-treemap-widget.aspx)
- [API Breaking Changes in Flutter DataGrid in 2021 Volume 1](https://www.syncfusion.com/blogs/post/api-breaking-changes-in-flutter-datagrid-in-2021-volume-1.aspx)
- [How to Sort Data in Syncfusion Flutter Data Tables Based on Multiple Columns](https://www.syncfusion.com/blogs/post/how-to-sort-data-in-syncfusion-flutter-data-tables-based-on-multiple-columns.aspx)
