Reputation: 59
Hy, I am working on a project, in which I use table_calender to create events and save them in database, i have successfully added then in the database, problems come when i have to retrieve them, when there is only one event in database it shows a maker on the calender date according to it, but when there is more than one repeated date, it should add another marker on that date again, but it gives the exception, is says that the key is null in map when i add another marker on same date. exception is at _events[mee.dateTime].add(meetingInfo[i]['m_agenda']);
for(int i=0; i<meetingInfo.length;i++)
{
if (_events[mee.dateTime] != null)
{
dateWithT=meetingInfo[i]['m_date'].replaceAll(new RegExp(r'[^\w\s]+'),'');
dateWithT=dateWithT.replaceAll(' ', '');
dateWithT=dateWithT+"000000";
dateWithT = dateWithT.substring(0, 8) + 'T' + dateWithT.substring(8);
mee.dateTime = DateTime.parse(dateWithT);
_events[mee.dateTime].add(meetingInfo[i]['m_agenda']);
}
else
{
dateWithT=meetingInfo[i]['m_date'].replaceAll(new RegExp(r'[^\w\s]+'),'');
dateWithT=dateWithT.replaceAll(' ', '');
dateWithT=dateWithT+"000000";
dateWithT = dateWithT.substring(0, 8) + 'T' + dateWithT.substring(8);
mee.dateTime = DateTime.parse(dateWithT);
_events[mee.dateTime] = [meetingInfo[i]['m_agenda']];
}
}
meeting.dart
import 'package:flutter/material.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:intl/intl.dart';
import 'notifcation_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:table_calendar/table_calendar.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'variables.dart';
meeting mee = new meeting();
class AddMeeting extends StatefulWidget {
@override
_AddMeetingeState createState() => _AddMeetingeState();
}
class _AddMeetingeState extends State<AddMeeting> {
List meetDate;
CalendarController _controller;
Map<DateTime, List<dynamic>> _events;
List<dynamic> _selectedEvents;
TextEditingController _eventController;
// SharedPreferences prefs;
@override
void initState() {
super.initState();
_controller = CalendarController();
_eventController = TextEditingController();
_events = {};
_selectedEvents = [];
getIdAndGetMeetings();
}
String dateWithT;
String emailFromSharedPref, meetingAdded;
Map smData;
List meetingInfo, customerInfo;
Future getIdAndGetMeetings() async {
// getting email from SharedPreferences
SharedPreferences prefs = await SharedPreferences.getInstance();
emailFromSharedPref = prefs.getString('email');
// getting saleManager info using email
var url = "http://..../getSaleMangerDetal.php";
var response = await http.post(url, body: {
"m_email": emailFromSharedPref,
});
smData = jsonDecode(response.body);
// getting customer info using saleManagerID
var customerInfoUrl = "http://..../calender/getCustomerInfo.php";
var customerInfoResponse = await http.post(customerInfoUrl, body: {
"sm_id": smData['manager_id'],
});
// saving customer info in the list, because there are many dict in the list
customerInfo = jsonDecode(customerInfoResponse.body);
// get meetings details from server using saleManager Id
var getmeetingUrl = "http://..../getMeetings.php";
var getMeetiongResponse = await http.post(getmeetingUrl, body: {
"manager_id": smData['manager_id'],
});
meetingInfo = jsonDecode(getMeetiongResponse.body);
print(meetingInfo);
for(int i=0; i<meetingInfo.length;i++)
{
if (_events[mee.dateTime] != null)
{
dateWithT=meetingInfo[i]['m_date'].replaceAll(new RegExp(r'[^\w\s]+'),'');
dateWithT=dateWithT.replaceAll(' ', '');
dateWithT=dateWithT+"000000";
dateWithT = dateWithT.substring(0, 8) + 'T' + dateWithT.substring(8);
mee.dateTime = DateTime.parse(dateWithT);
_events[mee.dateTime].add(meetingInfo[i]['m_agenda']);
}
else
{
dateWithT=meetingInfo[i]['m_date'].replaceAll(new RegExp(r'[^\w\s]+'),'');
dateWithT=dateWithT.replaceAll(' ', '');
dateWithT=dateWithT+"000000";
dateWithT = dateWithT.substring(0, 8) + 'T' + dateWithT.substring(8);
mee.dateTime = DateTime.parse(dateWithT);
_events[mee.dateTime] = [meetingInfo[i]['m_agenda']];
}
}
}
Map<String, dynamic> encodeMap(Map<DateTime, dynamic> map) {
Map<String, dynamic> newMap = {};
map.forEach((key, value) {
newMap[key.toString()] = map[key];
});
return newMap;
}
Map<DateTime, dynamic> decodeMap(Map<String, dynamic> map) {
Map<DateTime, dynamic> newMap = {};
map.forEach((key, value) {
newMap[DateTime.parse(key)] = map[key];
});
return newMap;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Calendar'),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TableCalendar(
events: _events,
// initialCalendarFormat: CalendarFormat.week,
calendarStyle: CalendarStyle(
canEventMarkersOverflow: true,
todayColor: Colors.orange,
selectedColor: Theme.of(context).primaryColor,
todayStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18.0,
color: Colors.white)),
headerStyle: HeaderStyle(
centerHeaderTitle: true,
formatButtonDecoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(20.0),
),
formatButtonTextStyle: TextStyle(color: Colors.white),
formatButtonShowsNext: false,
),
startingDayOfWeek: StartingDayOfWeek.monday,
onDaySelected: (date, events) {
setState(() {
_selectedEvents = events;
});
},
builders: CalendarBuilders(
selectedDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10.0)),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)),
todayDayBuilder: (context, date, events) => Container(
margin: const EdgeInsets.all(4.0),
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.orange,
borderRadius: BorderRadius.circular(10.0)),
child: Text(
date.day.toString(),
style: TextStyle(color: Colors.white),
)),
),
calendarController: _controller,
),
..._selectedEvents.map((event) => ListTile(
title: Text(event),
)),
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: _showAddDialog,
),
);
}
_showAddDialog() async {
await showDialog(
context: context,
builder: (context) => AlertDialog(
content: TextField(
controller: _eventController,
),
actions: <Widget>[
FlatButton(
child: Text("Save"),
onPressed: ()
{
// if (_eventController.text.isEmpty) return;
// if (_events[_controller.selectedDay] != null) {
// _events[_controller.selectedDay]
// .add(_eventController.text);
String asd = _controller.selectedDay.toString();
meetDate = asd.split(' ');
addMeetingToDatabase(meetDate);
// }
// else
// {
// // _events[_controller.selectedDay] = [
// // _eventController.text
// // ];
// String asd = _controller.selectedDay.toString();
// meetDate = asd.split(' ');
// addMeetingToDatabase(meetDate);
// // print(_controller.selectedDay);
// }
// prefs.setString("events", json.encode(encodeMap(_events)));
_eventController.clear();
Navigator.pop(context);
},
)
],
));
setState(() {
_selectedEvents = _events[mee.dateTime];
});
}
addMeetingToDatabase(List meetDate2) async {
// print(meetDate2[0]);
var getmeetingUrls = "http://..../addMeeting.php";
var getMeetiongResponses = await http.post(getmeetingUrls, body: {
"sm_id": smData['manager_id'],
"c_id": '2',
"agenda": _eventController.text,
"date": meetDate2[0],
// "time":smData['manager_id'],
});
meetingAdded = jsonDecode(getMeetiongResponses.body);
print(meetingAdded);
}
}
Upvotes: 1
Views: 2739
Reputation: 5388
Seems like you are trying to call a method on an object that is not there in the Map
.
mee.dateTime = DateTime.parse(dateWithT);
_events[mee.dateTime].add(meetingInfo[i]['m_agenda']);
In the above code, if mee.dateTime
isn't present in the map it return null
which is currently causing your exception.
Now, you have a check
if (_events[mee.dateTime] != null) {
...
mee.dateTime = DateTime.parse(dateWithT);
_events[mee.dateTime].add(meetingInfo[i]['m_agenda']);
}
So basically, the dateTime
which is there in the Map which you checked before entering this section is now updated inside the block. Now you are not checking whether the new dateTime is present in the Map or not.
You have a logical problem in your code.
Upvotes: 2