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);
   }
  }