ImAZ
ImAZ

Reputation: 59

NoSuchMethodError: The method 'add' was called on null. Receiver: null

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

Answers (1)

Sisir
Sisir

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

Related Questions