Flutter: How to get data from api and bind in PaginatedDataTable

1,017

What you need is a change notifier.

Lets make a quick example.

Here is my model:

{
    "id":1,
    "name": "John Doe",
    "username":"johndoe",
    "email":"[email protected]",
    "address":"address",
    "phone":"1234567890",
    "website":"johndoe.com",
    "company":"johndoe pty ltd"
}

then my flutter data model will look something like this:

import 'dart:convert';

List<UserModel> userModelFromJson(String str) =>
    List<UserModel>.from(json.decode(str).map((x) => UserModel.fromJson(x)));

String userModelToJson(List<UserModel> data) =>
    json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class UserModel {
  UserModel({
    this.id,
    this.name,
    this.username,
    this.email,
    this.address,
    this.phone,
    this.website,
    this.company,
  });

  int id;
  String name;
  String username;
  String email;
  Address address;
  String phone;
  String website;
  Company company;

  factory UserModel.fromJson(Map<String, dynamic> json) => UserModel(
        id: json["id"],
        name: json["name"],
        username: json["username"],
        email: json["email"],
        address: Address.fromJson(json["address"]),
        phone: json["phone"],
        website: json["website"],
        company: Company.fromJson(json["company"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "username": username,
        "email": email,
        "address": address.toJson(),
        "phone": phone,
        "website": website,
        "company": company.toJson(),
      };
}

Next I will create a Data Change Notifier for the UserModel Class:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart' show PaginatedDataTable;

class UserDataNotifier with ChangeNotifier {
  UserDataNotifier() {
    fetchData();
  }

  List<UserModel> get userModel => _userModel;


  var _userModel = <UserModel>[]

  Future<void> fetchData() async {
    _userModel = await Api.fetchData();
    notifyListeners();
  }
}

Notice that we are using _userModel = await Api.fetchData(); this can be your own implementation for an API. If you need assistance with this, look into Dio for Flutter. Data is fetched on the init of the ChangeNotifier.

Next we will create a datasource to house all the data:

import 'package:flutter/material.dart';

class UserDataTableSource extends DataTableSource {
  UserDataTableSource({
    @required List<UserModel> userData,
    @required this.onRowSelect,
  })  : _userData = userData,
        assert(userData != null);

  final List<UserModel> _userData;
  final OnRowSelect onRowSelect;

  @override
  DataRow getRow(int index) {
    assert(index >= 0);

    if (index >= _userData.length) {
      return null;
    }
    final _user = _userData[index];

    return DataRow.byIndex(
      index: index, // DON'T MISS THIS
      cells: <DataCell>[
        DataCell(Text('${_user.name}')),
        DataCell(Text('${_user.username}')),
        DataCell(Text('${_user.email}')),
        DataCell(Text('${_user.address}')),
        DataCell(Text('${_user.phone}')),
        DataCell(Text('${_user.website}')),
        DataCell(Text('${_user.company}')),
      ],
    );
  }

  @override
  bool get isRowCountApproximate => false;

  @override
  int get rowCount => _userData.length;

  @override
  int get selectedRowCount => 0;
  
}

Lastly we will use this Change Notifier and DataSource within our Widget:

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class DataTableScreen extends StatelessWidget {
  const DataTableScreen({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //
    return Stack(
      // scrollDirection: Axis.horizontal,
      children: [
        ChangeNotifierProvider(
            create: (_) => UserDataNotifier(),
            child: _InternalWidget()
        )
      ],
    );
  }
}

class _InternalWidget extends StatelessWidget {
  const _InternalWidget({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //
    final _provider = context.watch<UserDataNotifier>();
    final _model = _provider.userModel;

    if (_model.isEmpty) {
      return const SizedBox.shrink();
    }
    final _dtSource = UserDataTableSource(
      userData: _model,
    );

    return PaginatedDataTable(
      source: _dtSource,
      horizontalMargin: 10,
      columnSpacing: 10,
      showFirstLastButtons: true,
      rowsPerPage: PaginatedDataTable.defaultRowsPerPage,
      columns: const [
        DataColumn(
          label: Text("Name"),
        ),
        DataColumn(
          label: Text("User Name"),
        ),
        DataColumn(
          label: Text("E-mail"),
        ),
        DataColumn(
          label: Text("Address"),
        ),
        DataColumn(
          label: Text("Phone"),
        ),
        DataColumn(
          label: Text("Website"),
        ),
        DataColumn(
          label: Text("Company"),
        )
      ],
    );
  }
}
Share:
1,017
Admin
Author by

Admin

Updated on December 31, 2022

Comments

  • Admin
    Admin over 1 year
    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    
    class DataTableDemo extends StatelessWidget {
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Service History'),
          ),
          body: ListView(
            padding: const EdgeInsets.all(16),
            children: [
              PaginatedDataTable(
                header: Text('Service Details'),
                rowsPerPage: 4,
                columns: [
                  DataColumn(label: Text('SrNo.')),
                  DataColumn(label: Text('Customer Name')),
                  DataColumn(label: Text('Mobile Number')),
                  DataColumn(label: Text('Address')),
                  DataColumn(label: Text('Company')),
                  DataColumn(label: Text('Model')),
                  DataColumn(label: Text('REGNo')),
                ],
                source: _DataSource(context),
              ),
            ],
          ),
        );
      }
    }
     fetchSummary() async {
       
      final response = await http.get('https://api');
    
      if (response.statusCode == 200) {
          var parsed = json.decode(response.body);    
        List jsonResponse = parsed["Table"] as List;
        return jsonResponse.map((job) => new _Row.fromJson(job)).toList();
      } else {
        print('Error, Could not load Data.');
        throw Exception('Failed to load Data');
      }
    }
    class _Row {
      _Row(
        this.srNo,
        this.customerName,
        this.mobileNumber,
        this.address,
        this.company,
        this.model,
        this.rEGNo,
      );
    
      final int srNo;
      final String customerName;
      final String mobileNumber;
      final String address;
      final String company;
      final String model;
      final String rEGNo;
    
      bool selected = false;
       factory _Row.fromJson(Map<String, dynamic> json) {
        return _Row(
           json['SrNo'],
           json['CustomerName'],
           json['MobileNumber'],
            json['Address'],
            json['Company'],
            json['Model'],
            json['REGNo'],
        );
      }
    }
    
    class _DataSource extends DataTableSource {
      _DataSource(this.context) {
        _rows = 
          fetchSummary();
        
      }
    
      final BuildContext context;
      List<_Row> _rows;
    
      int _selectedCount = 0;
    
      @override
      DataRow getRow(int index) {
        assert(index >= 0);
        if (index >= _rows.length) return null;
        final row = _rows[index];
        return DataRow.byIndex(
          index: index,
          //selected: row.selected,
          onSelectChanged: (value) {
            if (row.selected != value) {
              _selectedCount += value ? 1 : -1;
              assert(_selectedCount >= 0);
              row.selected = value;
              notifyListeners();
            }
          },
          cells: [
            DataCell(Text(row.srNo.toString())),
            DataCell(Text(row.customerName)),
            DataCell(Text(row.mobileNumber)),
            DataCell(Text(row.address)),
            DataCell(Text(row.company)),
            DataCell(Text(row.model)),
            DataCell(Text(row.rEGNo)),
          ],
        );
      }
    
      @override
      int get rowCount => _rows.length;
    
      @override
      bool get isRowCountApproximate => false;
    
      @override
      int get selectedRowCount => _selectedCount;
    }
    

    i have tried this code but getting error when bind data. when i call API and get data (Json format) from server, unable to convert data and got error.how can i convert my data and bind into PaginatedDataTable.

    Source Code From: [https://material.io/components/data-tables/flutter#theming-data-tables] .