How to Display PaginatedDataTable Using API Data in Flutter

In this blog post, let’s learn how to create a paginated data table in Flutter using the PaginatedDataTable widget. We will be fetching data from an API and displaying it in a tabular format, allowing the user to easily navigate through the data.

Presenting information in a tabular format can be computationally intensive in Flutter, as the data must be evaluated twice in order to properly format the table- once to determine the dimensions of each column, and again to place the data in the table.

When dealing with large amounts of data, it’s always recommended to use the PaginatedDataTable widget instead of DataTable widget. This widget automatically divides the data into multiple pages, thus reducing the load.

First of all, install the http package into your Flutter project by following the instructions given here. Thus the API consumption will become easier.

We fetch data from this endpoint- https://jsonplaceholder.typicode.com/albums and show the response as a paginated table. Following is the sample response format from the API.

[
  {
    "userId": 1,
    "id": 1,
    "title": "quidem molestiae enim"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "sunt qui excepturi placeat culpa"
  },
]

Now, see the complete code given below.

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(const MyApp());
}

class Data {
  final int userId;
  final int id;
  final String title;

  Data({required this.userId, required this.id, required this.title});

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(useMaterial3: true),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Flutter PaginatedDataTable Example'),
        ),
        body: const MyStatefulWidget());
  }
}

class MyStatefulWidget extends StatefulWidget {
  const MyStatefulWidget({super.key});

  @override
  State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}

class _MyStatefulWidgetState extends State<MyStatefulWidget> {
  List<Data> data = [];

  fetchData() async {
    var url = Uri.parse('https://jsonplaceholder.typicode.com/albums');
    final response = await http.get(url);
    if (response.statusCode == 200) {
      List jsonResponse = json.decode(response.body);
      setState(() {
        data = jsonResponse.map((data) => Data.fromJson(data)).toList();
      });
    } else {
      throw Exception('Unexpected error occured!');
    }
  }

  @override
  void initState() {
    super.initState();
    fetchData();
  }

  @override
  Widget build(BuildContext context) {
    return PaginatedDataTable(columns: const [
      DataColumn(label: Text('USER ID'), numeric: true),
      DataColumn(label: Text('ID'), numeric: true),
      DataColumn(label: Text('TITLE')),
    ], source: MyData(data));
  }
}

class MyData extends DataTableSource {
  final List<Data> data;
  MyData(this.data);

  @override
  int get rowCount => data.length;

  @override
  bool get isRowCountApproximate => false;

  @override
  int get selectedRowCount => 0;

  @override
  DataRow getRow(int index) {
    final Data result = data[index];
    return DataRow.byIndex(index: index, cells: <DataCell>[
      DataCell(Text(result.userId.toString())),
      DataCell(Text(result.id.toString())),
      DataCell(Text(result.title)),
    ]);
  }
}

MyStatefulWidget is a StatefulWidget that contains a List object that stores the data that is fetched from the API. The fetchData() function uses the http package to make a GET request to the API and parse the response into a list of Data objects.

The initState() function calls fetchData() so that the data is fetched when the widget is first created.

We have a PaginatedDataTable widget, with the columns parameter set to a list of DataColumn objects that define the columns of the table. The source parameter is set to an instance of MyData which implements the DataTableSource that provides the data for the PaginatedDataTable widget.

MyData takes the list of Data objects as a constructor parameter and overrides the methods of DataTableSource to provide the data to the table.

MyData class contains the methods like get rowCount, isRowCountApproximate, get selectedRowCount, getRow which are required by the DataTableSource class.

The PaginatedDataTable widget uses this data to display the data in a paginated table.

flutter paginateddatatable from API

That’s how you add PaginatedDataTable with API data in Flutter.

Similar Posts

Leave a Reply