Reputation: 1
Flutter 3.10: FutureBuilder with PaginatedDataTable from GET Response, but snapshot.data is Empty.
I am creating an app which include a User List page showing records in a PaginatedDataTable inside a FutureBuilder. The PaginatedDataTable includes a DataTableSource, which relies upon a GET request/response which returns a List/, where User refers to a model.
EDITED: Replaced original code samples below. Revised to consolidate into single file for debugging, and included more print statements to assist with debugging through console.
PROBLEM from Console:
{alias: ALIAS, password: password}
AsyncSnapshot<List>(ConnectionState.waiting, null, null, null) null snapshot.hasData failed
200 [{"id":6,"alias":"username","name_first":"fIrStNaMe","name_last":"lAsTnAmE","email":"[email protected]","phone":"2222222222","date_birth":"2000-12-01"},{"id":1,"alias":"ALIAS","name_first":"FiRsTnAmE","name_last":"LaStNaMe","email":"[email protected]","phone":"9999999999","date_birth":"2000-01-31"}]
user_fetch: after response received [{id: 6, alias: username, name_first: fIrStNaMe, name_last: lAsTnAmE, email: [email protected], phone: 2222222222, date_birth: 2000-12-01}, {id: 1, alias: ALIAS, name_first: FiRsTnAmE, name_last: LaStNaMe, email: [email protected], phone: 9999999999, date_birth: 2000-01-31}]
user_fetch, 200 response received, before return list [{id: 6, alias: username, name_first: fIrStNaMe, name_last: lAsTnAmE, email: [email protected], phone: 2222222222, date_birth: 2000-12-01}, {id: 1, alias: ALIAS, name_first: FiRsTnAmE, name_last: LaStNaMe, email: [email protected], phone: 9999999999, date_birth: 2000-01-31}]
AsyncSnapshot<List>(ConnectionState.done, null, Expected a value of type 'FutureOr<List>', but got one of type 'List', ) null snapshot.hasData failed
CODE BELOW:
import 'dart:convert';
import 'package:flutter_axum/providers/url.dart';
import 'package:flutter/material.dart';
import 'package:flutter_axum/providers/user_auth.dart';
//import 'package:flutter_axum/providers/user_data_table_source.dart';
//import 'package:flutter_axum/providers/user_fetch.dart';
//import 'package:flutter_axum/widgets/paginated_data_table.dart';
import 'package:http/http.dart' as http;
import '../models/user.dart';
import '../providers/user_secure_storage.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
//final DataTableSource source = UserDataTableSource();
//final columns = UserDataTableSource().getColumns();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('User Paginated Data Table'),
actions: [
IconButton(
icon: const Icon(Icons.exit_to_app),
onPressed: () {
///logout
AuthenticationProvider().logoutUser(context: context);
}),
],
),
body: FutureBuilder(
future: getUsers(),
builder: (context, snapshot) {
print(snapshot);
print(snapshot.data);
if (ConnectionState.active != null && !snapshot.hasData) {
print("snapshot.hasData failed");
return Center(child: Text('Loading'));
}
if (ConnectionState.done != null && snapshot.hasError) {
print("snapshot.hasError failed");
return Center(child: Text(snapshot.error.toString()));
} else {
print("snapshot reaches PaginatedDataTable");
return PaginatedDataTable(
columns: getColumns(),
source: UserDataTableSource(source: snapshot.data! as List<User>)
);
}
}
)
);
}
}
Future<List<User>> getUsers() async {
final StorageService storageService = StorageService();
final bearer = await storageService.readSecureData('token');
final url = BaseUrl.baseUrl;
String _url = "$url/user/list";
try {
final request = await http.get(Uri.parse(_url), headers: {'Access-Control-Allow-Origin': '*', 'Authorization': 'Bearer $bearer'});
print(request.statusCode);
print(request.body);
if (request.statusCode == 200 || request.statusCode == 201){
final list = json.decode(request.body);
print("user_fetch: after response received");
print(list);
if (json.decode(request.body) == null) {
return list;
} else {
print("user_fetch, 200 response received, before return list");
print(list);
return list;
}
} else {
List<User> list = [];
return list;
}
} catch (e) {
return Future.error(e.toString());
}
}
class UserDataTableSource extends DataTableSource {
UserDataTableSource({required source}) : userList = source;
final List<User> userList;
@override
DataRow getRow(int index) {
final User user = userList[index];
return DataRow.byIndex(index: index, cells: [
DataCell(Text('${user.id}')),
DataCell(Text(user.alias)),
DataCell(Text(user.nameFirst)),
DataCell(Text(user.nameLast)),
DataCell(Text(user.email)),
DataCell(Text(user.phone)),
DataCell(Text(user.dateBirth)),
//const DataCell(Text("Edit|Delete")),
]);
}
@override
bool get isRowCountApproximate => false;
@override
int get rowCount => userList.length;
@override
int get selectedRowCount => 0;
}
const String colID = 'ID';
const String colAlias = 'Alias';
const String colNameFirst = 'First Name';
const String colNameLast = 'Last Name';
const String colEmail = 'Email';
const String colPhone = 'Phone';
const String colDateBirth = 'Date of Birth';
List<DataColumn> getColumns(){
final List<DataColumn> columns =
<DataColumn>[
const DataColumn(
label: Text(colID),
tooltip: colID,
),
const DataColumn(
label: Text(colAlias),
tooltip: colAlias,
),
const DataColumn(
label: Text(colNameFirst),
tooltip: colNameFirst,
),
const DataColumn(
label: Text(colNameLast),
tooltip: colNameLast,
),
const DataColumn(
label: Text(colEmail),
tooltip: colEmail,
),
const DataColumn(
label: Text(colPhone),
tooltip: colPhone,
),
const DataColumn(
label: Text(colDateBirth),
tooltip: colDateBirth,
),
];
return columns;
}
In the PROBLEM output above, you can see the print statements return the Response Status Code, followed by the response.body, then a print of the list following json.decode.
The output shows the NULL snapshot while ConnectionState is 'waiting', but then it returns empty with an error message, "Expected a value of type 'FutureOr<List>', but got one of type 'List'" once ConnectionState returns 'done'.
Any feedback or guidance would be greatly appreciated!
Upvotes: 0
Views: 111