Flutter:在 null 上调用了方法 'map'。 |将 API 响应添加到数据表行
Flutter: The method 'map' was called on null. | Adding API Response into datatable row
我正在尝试将 api 响应数据添加到数据表行中。
我的 api 回复是这样的
{AccessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vYmFyIiwiaWF0IjoxNjIzNzc3MDA0LCJleHAiOjE2MjM3Nzg4MDR9.rp08n01FqkA0lklabii5Ueo0EP0-0Sj4roaSVi-JWQc, data: [{_id: 60c8d7c3ed211c38c4fb2f1b, username: abc, Date: 2021-06-15, TimeIn: 9:39:31 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}, {_id: 60c8d8abed211c38c4fb2f1c, username: abc, Date: 2021-06-15, TimeIn: 9:43:23 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}, {_id: 60c8dee3ed211c38c4fb2f1d, username:abc, Date: 2021-06-15, TimeIn: 10:09:55 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}]}
我想将 Date、timeIn 和 timeOut 放入数据表行
这是我的全部代码!!
class MyAttendance extends StatefulWidget {
@override
_MyAttendanceState createState() => _MyAttendanceState();
}
class _MyAttendanceState extends State<MyAttendance> {
List<History> _historyList;
String getdate="";
void _getDate() {
final String formattedDateTime =
DateFormat('MM').format(DateTime.now()).toString();
setState(() {
getdate = formattedDateTime;
print("date "+getdate);
});
}
_userDetails() async{
SharedPreferences myPrefs=await SharedPreferences.getInstance();
setState(() {
getname=myPrefs.getString('name');
});
}
void initState() {
_userDetails();
_getRecord();
_getDate();
}
_getRecord() async{
Dio dio=new Dio();
var data={
'username':getname,
'month':getdate
};
await dio
.post(localhostUrlAttendanceHistory,data: json.encode(data))
.then((onResponse)async {
var jsonData=onResponse.data['data'];
List<History> historyList = [];
for (var h in jsonData) {
History history = History(h["Date"], h["TimeIn"], h["TimeOut"],);
historyList.add(history);
print(history.date+" "+history.timeIn+" "+history.timeOut);
}
this.setState(() {
_historyList = historyList;
});
}).catchError((onerror){
print(onerror.toString());
//showAlertDialog(context);
});
}
Widget attendanceHistory()=>
DataTable(columns: <DataColumn>[
DataColumn(label: Text("Date"),numeric: true),
DataColumn(label: Text("Time in"),numeric: true),
DataColumn(label: Text("Time out"),numeric: true)
],
rows:
_historyList
.map((element)=>DataRow(
cells: <DataCell>[
DataCell(Text(element.date)),
DataCell(Text(element.timeIn)),
DataCell(Text(element.timeOut)),
])
));
@override
Widget build(BuildContext context) {
return Scaffold(
body:
Stack(children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(135, 210, 10, 0),
child:
ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
)),
child: Text('Submit',style: TextStyle(fontSize: 20),),
onPressed: _getRecord,
),
)),
Container(
padding: EdgeInsets.fromLTRB(25, 270, 10, 0),
child: attendanceHistory(),) //here i'm calling my datatable widget
]));
}
}
class History {
final String date;
final String timeIn;
final String timeOut;
History(this.date, this.timeIn, this.timeOut);
}
这里是错误
════════小部件库捕获异常═════════════════════════════════ ═══
在 null 上调用了方法 'map'。
接收者:空
尝试调用:map(Closure: (History) => DataRow)
当我 运行 应用程序时,它会显示这个。
更新
这是我从 JsonData 得到的
[{_id: 60c8d7c3ed211c38c4fb2f1b, 用户名: abc, 日期: 2021-06-15, TimeIn: 9:39:31 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}, {_id: 60c8d8abed211c38c4fb2f1c, 用户名: abc, 日期: 2021-06-15, TimeIn: 9:43:23 AM, TimeOut: , manager_id: -, code: se-001 , __v: 0}, {_id: 60c8dee3ed211c38c4fb2f1d, 用户名: abc, 日期: 2021-06-15, TimeIn: 10:09:55 AM, TimeOut: , manager_id: -, code: se -001, __v: 0}]
这是它的快照
请帮助,如果知道如何做到这一点。
您应该使用 FutureBuilder
小部件在数据可用时更新您的用户界面。您提供的代码尝试在收到数据之前构建小部件。这导致 _historyList
仍然为空。
// Update the attendenceHistory method to this.
Widget attendanceHistory(List<History> historyList)=>
DataTable(columns: <DataColumn>[
DataColumn(label: Text("Date"),numeric: true),
DataColumn(label: Text("Time in"),numeric: true),
DataColumn(label: Text("Time out"),numeric: true)
],
rows:
historyList
.map((element)=>DataRow(
cells: <DataCell>[
DataCell(Text(element.date)),
DataCell(Text(element.timeIn)),
DataCell(Text(element.timeOut)),
])
));
// Change this.
Container(
padding: EdgeInsets.fromLTRB(25, 270, 10, 0),
child: attendanceHistory(),
),
// Into this
Container(
padding: EdgeInsets.fromLTRB(25, 270, 10, 0),
child: FutureBuilder(
future: _getRecord(),
builder: (BuildContext context, AsyncSnapshot<List<History>> snapshot) {
// Check if the data has been received.
if (snapshot.hasData) {
// Return the widget and provide the received data.
return attendenceHistory(snapshot.data),
}
}
),
),
// Add a type to the _getRecord() method.
Future<List<History>> _getRecord() async{
Dio dio = new Dio();
var data = {
'username':getname,
'month':getdate
};
try {
final response = await dio.post(
localhostUrlAttendanceHistory,
data: json.encode(data),
);
var jsonData = response['data'];
List<History> historyList = [];
for (var h in jsonData) {
History history = History(
h["Date"],
h["TimeIn"],
h["TimeOut"],
);
historyList.add(history);
}
return historyList;
} catch (e) {
print(e.toString());
//showAlertDialog(context);
}
}
我正在尝试将 api 响应数据添加到数据表行中。
我的 api 回复是这样的
{AccessToken: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiZm9vYmFyIiwiaWF0IjoxNjIzNzc3MDA0LCJleHAiOjE2MjM3Nzg4MDR9.rp08n01FqkA0lklabii5Ueo0EP0-0Sj4roaSVi-JWQc, data: [{_id: 60c8d7c3ed211c38c4fb2f1b, username: abc, Date: 2021-06-15, TimeIn: 9:39:31 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}, {_id: 60c8d8abed211c38c4fb2f1c, username: abc, Date: 2021-06-15, TimeIn: 9:43:23 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}, {_id: 60c8dee3ed211c38c4fb2f1d, username:abc, Date: 2021-06-15, TimeIn: 10:09:55 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}]}
我想将 Date、timeIn 和 timeOut 放入数据表行
这是我的全部代码!!
class MyAttendance extends StatefulWidget {
@override
_MyAttendanceState createState() => _MyAttendanceState();
}
class _MyAttendanceState extends State<MyAttendance> {
List<History> _historyList;
String getdate="";
void _getDate() {
final String formattedDateTime =
DateFormat('MM').format(DateTime.now()).toString();
setState(() {
getdate = formattedDateTime;
print("date "+getdate);
});
}
_userDetails() async{
SharedPreferences myPrefs=await SharedPreferences.getInstance();
setState(() {
getname=myPrefs.getString('name');
});
}
void initState() {
_userDetails();
_getRecord();
_getDate();
}
_getRecord() async{
Dio dio=new Dio();
var data={
'username':getname,
'month':getdate
};
await dio
.post(localhostUrlAttendanceHistory,data: json.encode(data))
.then((onResponse)async {
var jsonData=onResponse.data['data'];
List<History> historyList = [];
for (var h in jsonData) {
History history = History(h["Date"], h["TimeIn"], h["TimeOut"],);
historyList.add(history);
print(history.date+" "+history.timeIn+" "+history.timeOut);
}
this.setState(() {
_historyList = historyList;
});
}).catchError((onerror){
print(onerror.toString());
//showAlertDialog(context);
});
}
Widget attendanceHistory()=>
DataTable(columns: <DataColumn>[
DataColumn(label: Text("Date"),numeric: true),
DataColumn(label: Text("Time in"),numeric: true),
DataColumn(label: Text("Time out"),numeric: true)
],
rows:
_historyList
.map((element)=>DataRow(
cells: <DataCell>[
DataCell(Text(element.date)),
DataCell(Text(element.timeIn)),
DataCell(Text(element.timeOut)),
])
));
@override
Widget build(BuildContext context) {
return Scaffold(
body:
Stack(children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(135, 210, 10, 0),
child:
ElevatedButton(
style: ButtonStyle(
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
)),
child: Text('Submit',style: TextStyle(fontSize: 20),),
onPressed: _getRecord,
),
)),
Container(
padding: EdgeInsets.fromLTRB(25, 270, 10, 0),
child: attendanceHistory(),) //here i'm calling my datatable widget
]));
}
}
class History {
final String date;
final String timeIn;
final String timeOut;
History(this.date, this.timeIn, this.timeOut);
}
这里是错误
════════小部件库捕获异常═════════════════════════════════ ═══ 在 null 上调用了方法 'map'。 接收者:空 尝试调用:map(Closure: (History) => DataRow)
当我 运行 应用程序时,它会显示这个。
更新
这是我从 JsonData 得到的
[{_id: 60c8d7c3ed211c38c4fb2f1b, 用户名: abc, 日期: 2021-06-15, TimeIn: 9:39:31 AM, TimeOut: , manager_id: -, code: se-001, __v: 0}, {_id: 60c8d8abed211c38c4fb2f1c, 用户名: abc, 日期: 2021-06-15, TimeIn: 9:43:23 AM, TimeOut: , manager_id: -, code: se-001 , __v: 0}, {_id: 60c8dee3ed211c38c4fb2f1d, 用户名: abc, 日期: 2021-06-15, TimeIn: 10:09:55 AM, TimeOut: , manager_id: -, code: se -001, __v: 0}]
这是它的快照
请帮助,如果知道如何做到这一点。
您应该使用 FutureBuilder
小部件在数据可用时更新您的用户界面。您提供的代码尝试在收到数据之前构建小部件。这导致 _historyList
仍然为空。
// Update the attendenceHistory method to this.
Widget attendanceHistory(List<History> historyList)=>
DataTable(columns: <DataColumn>[
DataColumn(label: Text("Date"),numeric: true),
DataColumn(label: Text("Time in"),numeric: true),
DataColumn(label: Text("Time out"),numeric: true)
],
rows:
historyList
.map((element)=>DataRow(
cells: <DataCell>[
DataCell(Text(element.date)),
DataCell(Text(element.timeIn)),
DataCell(Text(element.timeOut)),
])
));
// Change this.
Container(
padding: EdgeInsets.fromLTRB(25, 270, 10, 0),
child: attendanceHistory(),
),
// Into this
Container(
padding: EdgeInsets.fromLTRB(25, 270, 10, 0),
child: FutureBuilder(
future: _getRecord(),
builder: (BuildContext context, AsyncSnapshot<List<History>> snapshot) {
// Check if the data has been received.
if (snapshot.hasData) {
// Return the widget and provide the received data.
return attendenceHistory(snapshot.data),
}
}
),
),
// Add a type to the _getRecord() method.
Future<List<History>> _getRecord() async{
Dio dio = new Dio();
var data = {
'username':getname,
'month':getdate
};
try {
final response = await dio.post(
localhostUrlAttendanceHistory,
data: json.encode(data),
);
var jsonData = response['data'];
List<History> historyList = [];
for (var h in jsonData) {
History history = History(
h["Date"],
h["TimeIn"],
h["TimeOut"],
);
historyList.add(history);
}
return historyList;
} catch (e) {
print(e.toString());
//showAlertDialog(context);
}
}