Null check operator error when all variables have values? - flutter

I have this Table_Calendar that I am trying to add events to. For some reason, a null check error is thrown (all variables have values) and no data is added to my Map.
I added the line // ### THIS IS WHERE IT FAILS to show where the error pops (inside the _loadMeetupsForMonth function).
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:bark/helpers.dart' as helpers;
import 'package:loading_overlay/loading_overlay.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:line_icons/line_icons.dart';
import 'package:bark/addMeetup.dart';
class Meetups extends StatefulWidget {
Meetups({Key? key}) : super(key: key);
#override
_MeetupsState createState() => _MeetupsState();
}
class _MeetupsState extends State<Meetups> {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
Map<DateTime, List<CalendarEvent>> eventsForMonth =
new Map<DateTime, List<CalendarEvent>>();
bool _isLoading = false;
List<Widget> _meetups = [];
// ### ADD NEW MEETUP
_addMeetup() async {
var _user = FirebaseAuth.instance.currentUser;
if (_user != null) {
var doRefresh = await Navigator.of(context)
.push(new MaterialPageRoute(builder: (context) => AddMeetup()));
if (doRefresh == true || doRefresh == null) {
// Refresh calendar
}
} else {
// Not logged in. Show login popup.
helpers.showLoginCreateForm(context);
}
}
_loadMeetupsForMonth(DateTime _date) async {
DateTime _start = DateTime(_date.year, _date.month, 1);
DateTime _end = DateTime(_date.month < 12 ? _date.year : _date.year + 1,
_date.month < 12 ? _date.month + 1 : 1, 0);
print(_start);
print(_end);
print("Loading data START");
// Get all for month
QuerySnapshot querySnapshot = await _firestore
.collection('Meetups')
.where("is_deleted", isEqualTo: false)
.where("meetup_time", isGreaterThanOrEqualTo: _start)
.where("meetup_time", isLessThanOrEqualTo: _end)
.orderBy("meetup_time", descending: true)
.get();
if (querySnapshot.docs.isEmpty) {
print("No meetups for the month");
} else {
for (final doc in querySnapshot.docs) {
Timestamp _meetupTime = doc['meetup_time'] ?? DateTime.now();
CalendarEvent _event = new CalendarEvent(
title: doc["meetup_title"], postedBy: doc["poster_name"]);
// ### THIS IS WHERE IT FAILS
eventsForMonth[_meetupTime.toDate()]!.add(_event);
}
}
print(
"Loading data END: Event count = " + eventsForMonth.length.toString());
}
List<CalendarEvent> _getEventsForDay(DateTime day) {
print("Getting for day " + day.toString());
return eventsForMonth[day] ?? [];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(
LineIcons.chevronLeft,
color: Colors.black,
),
onPressed: () {
Navigator.of(context).pop();
},
),
actions: [
IconButton(
icon: Icon(
LineIcons.plus,
color: Colors.black,
),
onPressed: () => _addMeetup()),
],
elevation: 1,
title: Text(
"Meetups",
style: TextStyle(color: Colors.black),
),
backgroundColor: helpers.appBarColor,
foregroundColor: Colors.black,
),
body: Column(
children: [
TableCalendar(
onPageChanged: (focusedDay) => {_loadMeetupsForMonth(focusedDay)},
firstDay: DateTime.now(),
lastDay: DateTime.utc(2050, 12, 31),
focusedDay: DateTime.now(),
onDaySelected: (selectedDay, focusedDay) {
print(selectedDay);
},
eventLoader: (day) {
return _getEventsForDay(day);
},
),
],
),
);
}
#override
initState() {
eventsForMonth = new Map<DateTime, List<CalendarEvent>>();
_loadMeetupsForMonth(DateTime.now());
super.initState();
}
}
class CalendarEvent {
final String title;
final String postedBy;
CalendarEvent({required this.title, required this.postedBy});
}
The error is:
Unhandled Exception: Null check operator used on a null value
Anyone have a solution?

replacing eventsForMonth[_meetupTime.toDate()]!.add(_event); with
if(eventsForMonth[_meetupTime.toDate()]!=null)
eventsForMonth[_meetupTime.toDate()]!.add(_event);
else print("got null");
let me know if it solves

Related

CalendarScope isn't defined for the type 'CalendarApi'

I am facing a couple of issues, I'm trying to integrate my Google Calendar inside my app, but I get some issues "CalendarScope isn't defined for the type 'CalendarApi'.
As you can see in the screenshot below, there are some issues, but I don't know how fix them.
I am taking it from this code
https://www.syncfusion.com/kb/12647/how-to-load-the-google-calendar-events-to-the-flutter-calendar-sfcalendar-in-ios
I leave you here my code, could you please help me to figure out how to fix this?
class CalendarPage extends StatefulWidget {
#override
_CalendarPage createState() => _CalendarPage();
}
class _CalendarPage extends State<CalendarPage> {
final GoogleSignIn _googleSignIn = GoogleSignIn(
clientId:
'OAuth Client ID',
scopes: <String>[
googleAPI.CalendarApi.CalendarScope,
],
);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.blue[900],
centerTitle: true,
elevation: 0,
title: const Text("Calendario Scadenze",
style: TextStyle(color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600, fontFamily: "Raleway"),
),
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(
Icons.arrow_back_ios,
color: Colors.white,
),
onPressed: () {
Navigator.of(context).pop();
},
);
},
),
),
backgroundColor: Colors.white,
body: FutureBuilder(
future: getGoogleEventsData(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
return Stack(
children: [
SfCalendar(
view: CalendarView.month,
initialDisplayDate: DateTime(2020,7,15,9,0,0),
dataSource: GoogleDataSource(events: snapshot.data),
monthViewSettings: const MonthViewSettings(
appointmentDisplayMode:
MonthAppointmentDisplayMode.appointment),
),
snapshot.data != null
? Container()
: const Center(
child: CircularProgressIndicator(),
)
],
);
},
),
);
}
#override
void dispose(){
if(_googleSignIn.currentUser != null) {
_googleSignIn.disconnect();
_googleSignIn.signOut();
}
super.dispose();
}
Future<List<googleAPI.Event>> getGoogleEventsData() async {
final GoogleSignInAccount? googleUser = await _googleSignIn.signIn();
final GoogleAPIClient httpClient =
GoogleAPIClient(await googleUser!.authHeaders);
final googleAPI.CalendarApi calendarAPI = googleAPI.CalendarApi(httpClient);
final googleAPI.Events calEvents = await calendarAPI.events.list(
"primary",
);
final List<googleAPI.Event> appointments = <googleAPI.Event>[];
if (calEvents.items != null) {
for (int i = 0; i < calEvents.items!.length; i++) {
final googleAPI.Event event = calEvents.items![i];
if (event.start == null) {
continue;
}
appointments.add(event);
}
}
return appointments;
}
}
class GoogleDataSource extends CalendarDataSource {
GoogleDataSource({required List<googleAPI.Event> events}) {
appointments = events;
}
#override
DateTime getStartTime(int index) {
final googleAPI.Event event = appointments![index];
return event.start!.date ?? event.start!.dateTime!.toLocal();
}
#override
bool isAllDay(int index) {
return appointments![index].start.date != null;
}
#override
DateTime getEndTime(int index) {
final googleAPI.Event event = appointments![index];
return event.endTimeUnspecified != null
//&& event.endTimeUnspecified
? (event.start!.date ?? event.start!.dateTime!.toLocal())
: (event.end!.date != null
? event.end!.date!.add(const Duration(days: -1))
: event.end!.dateTime!.toLocal());
}
#override
String getLocation(int index) {
return appointments![index].location;
}
#override
String getNotes(int index) {
return appointments![index].description;
}
#override
String? getSubject(int index) {
final googleAPI.Event event = appointments![index];
return event.summary == null || event.summary!.isEmpty
? 'No Title'
: event.summary;
}
}
class GoogleAPIClient extends IOClient {
final Map<String, String> _headers;
GoogleAPIClient(this._headers) : super();
#override
Future<IOStreamedResponse> send(BaseRequest request) =>
super.send(request..headers.addAll(_headers));
#override
Future<Response> head(Object url, {required Map<String, String> headers}) =>
super.head(url, headers: headers..addAll(_headers));
}

Flutter list, chips and MultiSelect

I am trying to transfer the result of a query to a list but it is not working properly.
Below you will find the source code, it will be more clear.
I'm getting this error "type 'List' is not a subtype of type 'List'"
if the error is clear, I do not understand how to fix that.
I would like to get _allResults (contextName) into the list _context.
Many thanks for your help.
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:gtd_official_sharped_focused/models/context.dart';
import 'package:multi_select_flutter/multi_select_flutter.dart';
String taskImportant;
String taskUrgent;
class EngagePage_Sept_2021 extends StatefulWidget {
EngagePage_Sept_2021({Key key, }):super(key:key);//this.title}) : super(key: key);
// final String title;
#override
_EngagePage_Sept_2021State createState() => _EngagePage_Sept_2021State();
}
class _EngagePage_Sept_2021State extends State<EngagePage_Sept_2021> {
TextEditingController _searchController = TextEditingController();
Future resultsLoaded;
List _allResults = [];
List _resultsList = [];
#override
void initState() {
super.initState();
_selectedContext = _allResults;//_context;
_searchController.addListener(_onSearchChanged);
}
#override
void dispose(){
_searchController.removeListener(_onSearchChanged);
_searchController.dispose();
super.dispose();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
resultsLoaded = getUsersListOfTasksStreamSnapshots();
}
_onSearchChanged() {
searchResultsList();
}
/*static List<Contexts> _monTest = [
Contexts(contextName: ),
];
*/
static List<Contexts> _context = [. //Here, I would prefer to store the data.docs
Contexts(id: '1', contextName: "name 1"),
Contexts(id: '2', contextName: "name 2"),
Contexts(id: '3', contextName: "name 3"),
];
// static List<Contexts> _test = _allResults;
final _itemsContext = _context
.map((context) => MultiSelectItem<Contexts>(context, context.contextName))
.toList();
List<Contexts> _selectedContext = [];
final _multiSelectKeyContext = GlobalKey<FormFieldState>();
final _multiSelectKeyStatus = GlobalKey<FormFieldState>();
final _multiSelectKey4 = GlobalKey<FormFieldState>();
final _multiSelectKeyTime = GlobalKey<FormFieldState>();
searchResultsList() {
var showResults = [];
if(_searchController.text != "") {
for(var taskSnapshot in _allResults){
var title = Contexts.fromSnapshot(taskSnapshot).contextName.toLowerCase();
if(title.contains(_searchController.text.toLowerCase())) {
showResults.add(taskSnapshot);
}
}
} else {
showResults = List.from(_allResults);
}
setState(() {
_resultsList = showResults;
});
}
getUsersListOfTasksStreamSnapshots() async {
var data = await FirebaseFirestore.instance
.collection('Users')
.doc(FirebaseAuth.instance.currentUser.uid)
.collection('contexts')
.get();
setState(() {
_allResults = data.docs;
print(_allResults);
});
searchResultsList();
return 'complete';
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TEST CHIP'),
),
drawer: MyMenu(),
backgroundColor: Colors.white,
body: SingleChildScrollView(
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(20),
child: Column(
children: <Widget>[
//################################################################################################
// CONTEXT - MultiSelectBottomSheetField with validators
//################################################################################################
MultiSelectBottomSheetField<Contexts>(
key: _multiSelectKeyContext,
initialChildSize: 0.7,
maxChildSize: 0.95,
title: Text("Context"),
buttonText: Text("Context",style: TextStyle(fontSize: 18),),
items: _itemsContext,
searchable: true,
validator: (values) {
if (values == null || values.isEmpty) {
return "";
}
List<String> names = values.map((e) => e.contextName).toList();
return null;
},
onConfirm: (values) {
setState(() {
_selectedContext = values;
});
_multiSelectKeyContext.currentState.validate();
},
chipDisplay: MultiSelectChipDisplay(
onTap: (item) {
setState(() {
_selectedContext.remove(item);
});
_multiSelectKeyContext.currentState.validate();
},
),
),
SizedBox(height: 40),
//################################################################################################
// STATUS - MultiSelectBottomSheetField with validators
//################################################################################################
],
),
],
),
),
),
);
}
}
Model context
import 'package:cloud_firestore/cloud_firestore.dart';
class Contexts {
String id;
String contextName;
Contexts({
this.id,
this.contextName,
});
// formatting for upload to Firebase when creating the trip
Map<String, dynamic> toJson() =>
{
'context_Name': contextName,
};
//creating a Task object from a firebase snapshot
Contexts.fromSnapshot(DocumentSnapshot snapshot) :
id = snapshot.id,
contextName = snapshot['context_Name'];
}

Type mismatch in table_calendar

I am adding the table_calendar plugin to my flutter app. Most things are working so far thanks to the help I have been getting from y'all.
Here is the next issue I am getting. When I click on a date on the calendar I get the following error and then nothing happens.
======== Exception caught by gesture ===============================================================
The following _TypeError was thrown while handling a gesture:
type '_MapStream<QuerySnapshot<Map<String, dynamic>>, List<Event>>' is not a subtype of type 'Map<DateTime, List<dynamic>>'
When the exception was thrown, this was the stack:
#0 _AppointmentCalendarScreenState._onDaySelected.<anonymous closure> (package:tonnah/screens/appointment_calendar.dart:73:29)
Here is the code at line 73
void _onDaySelected(DateTime day, List events, List holidays) {
_eventsStream = _firestoreService.getEventStream(day);
setState(() {
_streamController.add(_eventsStream); <<<<< LINE 73
//_selectedEvents = _eventsStream;
});
}
Here is where I populate _eventsStream:
_eventsStream = _firestoreService.getEventStream(_selectedDay);
Stream<List<Event>> getEventStream(DateTime dateTime) {
return _db.collection('agency').doc(globals.agencyId).collection('event')
.where('eventDate', isGreaterThanOrEqualTo: Timestamp.fromDate(dateTime))
.snapshots().map((snapshot) => snapshot.docs
.map((document) => Event.fromFirestore(document.data()))
.toList());
}
It is also used here to put the event indicator on the calendar:
StreamBuilder(
//stream: _firestoreService.getEventStream(_selectedDay),
stream: _db.collection('agency').doc(globals.agencyId).collection('event')
.where('eventDate', isGreaterThanOrEqualTo: Timestamp.fromDate(_selectedDay))
.snapshots().map((snapshot) => snapshot.docs
.map((document) => Event.fromFirestore(document.data()))
.toList()),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Event> snapData;
//return snapData = snapshot.data;
_eventsStream = snapshot.data;
_eventsMap = convertToMap(_eventsStream);
//_selectedEventsMap = _eventsMap[_selectedDay] ?? [];
return _buildTableCalendar();
} else {
return CircularProgressIndicator();
}
},
),
I know there is a type difference but how do I make them match?
Here is the code from the calendar page:
// Example holidays
final Map<DateTime, List> _holidays = {
DateTime(2020, 1, 1): ['New Year\'s Day'],
DateTime(2020, 1, 6): ['Epiphany'],
DateTime(2020, 2, 14): ['Valentine\'s Day'],
DateTime(2020, 4, 21): ['Easter Sunday'],
DateTime(2020, 4, 22): ['Easter Monday'],
};
//final eventsRef = FirebaseFirestore.instance.collection('agency').doc(globals.agencyId).collection('event');
final _firestoreService = FirestoreService();
bool showSpinner = false;
var _eventsStream;
var _eventsMap;
final _selectedDay = DateTime.now();
class AppointmentCalendarScreen extends StatefulWidget {
AppointmentCalendarScreen({Key key, this.title}) : super(key: key);
final String title;
#override
_AppointmentCalendarScreenState createState() => _AppointmentCalendarScreenState();
}
class _AppointmentCalendarScreenState extends State<AppointmentCalendarScreen> with TickerProviderStateMixin {
//var _eventsList;
//Map<DateTime, List> _selectedEventsMap;
AnimationController _animationController;
CalendarController _calendarController;
StreamController<Map<DateTime, List>> _streamController;
#override
void initState() {
super.initState();
_streamController = StreamController();
_eventsStream = _firestoreService.getEventStream(_selectedDay);
_calendarController = CalendarController();
_animationController = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 400),
);
_animationController.forward();
}
#override
void dispose() {
_animationController.dispose();
_calendarController.dispose();
_streamController.close();
super.dispose();
}
void _onDaySelected(DateTime day, List events, List holidays) {
_eventsStream = _firestoreService.getEventStream(day);
setState(() {
_streamController.add(_eventsStream);
//_selectedEvents = _eventsStream;
});
}
void _onVisibleDaysChanged(DateTime first, DateTime last,
CalendarFormat format) {
}
void _onCalendarCreated(DateTime first, DateTime last,
CalendarFormat format) {
}
#override
Widget build(BuildContext context) {
final eventProvider = Provider.of<EventProvider>(context);
FirebaseFirestore _db = FirebaseFirestore.instance;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset('assets/images/Appbar_logo.png',
fit: BoxFit.cover, height: 56),
],
),
),
backgroundColor: Colors.white,
resizeToAvoidBottomInset: false,
body: Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
StreamBuilder(
stream: _firestoreService.getEventStream(_selectedDay),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Event> snapData;
_eventsStream = snapshot.data;
_eventsMap = convertToMap(_eventsStream);
//_selectedEventsMap = _eventsMap[_selectedDay] ?? [];
return _buildTableCalendar();
} else {
return CircularProgressIndicator();
}
},
),
const SizedBox(height: 8.0),
//_buildButtons(),
ElevatedButton(
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
globals.newAgency = true;
//eventProvider.saveEvent();
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (context) => AddEventScreen()));
setState(() {
showSpinner = false;
});
} catch (e) {
// todo: add better error handling
print(e);
}
},
child: Text('Add Event'),
),
const SizedBox(height: 8.0),
Expanded(child: _buildEventList()),
],
),
);
}
// Simple TableCalendar configuration (using Styles)
Widget _buildTableCalendar() {
return TableCalendar(
calendarController: _calendarController,
locale: 'en_US',
events: _eventsMap,
holidays: _holidays,
startingDayOfWeek: StartingDayOfWeek.sunday,
calendarStyle: CalendarStyle(
selectedColor: Colors.deepOrange[400],
todayColor: Colors.deepOrange[200],
markersColor: Colors.deepPurpleAccent,
outsideDaysVisible: false,
),
headerStyle: HeaderStyle(
formatButtonTextStyle:
TextStyle().copyWith(color: Colors.white, fontSize: 15.0),
formatButtonDecoration: BoxDecoration(
color: Colors.deepOrange[400],
borderRadius: BorderRadius.circular(16.0),
),
),
onDaySelected: _onDaySelected,
onVisibleDaysChanged: _onVisibleDaysChanged,
onCalendarCreated: _onCalendarCreated,
);
}
Widget _buildHolidaysMarker() {
return Icon(
Icons.add_box,
size: 20.0,
color: Colors.blueGrey[800],
);
}
Widget _buildEventList() {
final _db = FirebaseFirestore.instance;
return Container(
child: StreamBuilder<QuerySnapshot>(
//stream: FirestoreService().getEvent(),
stream: _db.collection('agency').doc(globals.agencyId).collection(
'event').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: const Text(
'Loading...',
style: TextStyle(
fontSize: 20, fontWeight: FontWeight.bold),
));
} else {
var doc = snapshot.data.docs;
return new ListView.builder(
itemCount: doc.length,
itemBuilder: (BuildContext context, int index) {
Event _event = Event.fromFirestore(
doc[index].data());
return ListTile(
isThreeLine: true,
title: Text(
'${_event.eventName ?? 'n/a'}',
style: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.blueAccent),
),
subtitle: Text.rich(TextSpan(
text:
//'${_event.eventName ?? 'n/a'}, '
'${_event.eventStartTime ?? 'n/a'}, '
'Duration: ${_event.eventDuration ?? 'n/a'}',
children: <TextSpan>[
TextSpan(
text:
'\n${_event.eventDescription ?? 'n/a'}',
style: TextStyle(
fontWeight: FontWeight.w900,
color: Colors.blueGrey),
)
])),
//trailing: Text('MLS#: ${_event.mlsNumber ?? 'n/a'}'),
onTap: () {
globals.newTrxn = false;
/*
Navigator.of(context).push(MaterialPageRoute(
builder: (context) =>
AddEventScreen(
doc[index].data())));
*/
},
);
}
);
}
},
),
);
}
Map<DateTime, List> convertToMap(List<Event> item) {
Map<DateTime, List> result;
for (int i = 0; i < item.length; i++) {
Event data = item[i];
//get the date and convert it to a DateTime variable
//DateTime currentDate = DateFormat('MM-dd-yyyy - kk:mm').format(data.eventDate);
DateTime currentDate = DateTime(data.eventDate.year, data.eventDate.month, data.eventDate.day, data.eventDate.hour, data.eventDate.minute);
List eventNames = [];
//add the event name to the the eventNames list for the current date.
//search for another event with the same date and populate the eventNames List.
for (int j = 0; j < item.length; j++) {
//create temp calendarItemData object.
Event temp = item[j];
//establish that the temp date is equal to the current date
if (data.eventDate == temp.eventDate) {
//add the event name to the event List.
eventNames.add(temp.eventName);
} //else continue
}
//add the date and the event to the map if the date is not contained in the map
if (result == null) {
result = {
currentDate: eventNames
};
} else {
result[currentDate] = eventNames;
}
return result;
}
}
}
You have to convert on type: Map<DateTime, List>.
Create method which will convert '_MapStream<QuerySnapshot<Map<String, dynamic>>, List>' on 'Map<DateTime, List>'
In your case: convert on 'Map<DateTime, List< "here you should add all data which you want to have in calendar view. Can be map or sth else">>
Actually, you need thre methods:
First: Convert method which I mentioned above. Method exemple below
final int _currentYearInt = DateTime.now().year;
final int _currentMonthInt =
int.parse(addZeroToNumberLowerThanTen(number: DateTime.now().month));
documentsList.forEach((doc) {
Map<DateTime, List<Shift>> _schedule = {};
// "days" is a properties with values: {"10" : [], "12": []}, where "10" is day of month"
doc['days'].forEach((k, v) {
int _shiftDay = int.parse(k);
if (calendarWithMarkedDates[
DateTime.utc(_currentYearInt, _currentMonthInt, _shiftDay)] ==
null) {
calendarWithMarkedDates[
DateTime.utc(_currentYearInt, _currentMonthInt, _shiftDay)] = [];
}
calendarWithMarkedDates[DateTime.utc(_currentYearInt, _currentMonthInt, _shiftDay)]!
.add( "your item. Can be object, map or what you want" );
});
});
Second: "calendarWithMarkedDates" is a LinkedHashMap, which holds all the marked dates. F.e. from server has response dates: 1.07, 5.07, 12.07. All dates after convert to LinkedHashMap are storing in this "calendarWithMarkedDates".
final calendarWithMarkedDates = LinkedHashMap<DateTime, List<Shift>>(
equals: isSameDay,
hashCode: getHashCode,
);
Third: "currentScheduleForDay" it is function which yu hava to invoke like a value of property "eventLoader" in TableCalendar without parameters.
It means:
good way currentScheduleForDay
bad way: currentScheduleForDay()
List<Shift> currentScheduleForDay(DateTime day) {
return currentCalendarWithMarkedDates[day] ?? [];
}
When use method currentScheduleForDay (without "()"), TableCalendar by it self made loops through all dates in month and inovke method for all day.

The getter 'name' was called on null

I'm trying to make an app that has basically the same mechanics as a simple todo-app. My problem is, when I try to open the screen where I can create a new project/todo(new_project_screen), there should be loaded some TextFields, but they don't. Instead, this error occurs. I tried several solutions from stackoverflow, but nothing worked and I have no idea why it's not working.(sorry for my bad english, I'm not a native xD)
Here is my code:
main.dart:
import 'package:flutter/material.dart';
import 'package:leisy/surface/main_screen.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(App());
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Leisy',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScreen(),
);
}
}
main_screen.dart:
import 'package:flutter/material.dart';
import 'dart:async';
import 'package:sqflite/sqflite.dart';
import 'package:leisy/db/database_helper.dart';
import 'package:leisy/model/project.dart';
import 'package:leisy/surface/settings_screen.dart';
import 'package:leisy/surface/new_project_screen.dart';
class MainScreen extends StatefulWidget {
#override
_MainScreenState createState() => _MainScreenState();
}
class _MainScreenState extends State<MainScreen> {
DatabaseHelper databaseHelper = DatabaseHelper();
List<Project> projectList = [];
int count = 0;
#override
Widget build(BuildContext context) {
if (projectList == null) {
projectList = <Project>[];
updateListView();
}
debugPrint("Building entire main screen scaffold");
return Scaffold(
appBar: AppBar(
title: Text("Leisy"),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Center(
child: Text(
"Menü",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {Navigator.of(context).pop()},
),
ListTile(
leading: Icon(Icons.add),
title: Text('Neues Projekt'),
onTap: () => {
Navigator.of(context).push(new MaterialPageRoute(
builder: (context) => new NewProjectScreen()))
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Einstellungen'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()))
},
)
],
),
),
body: getProjectListView(),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: navigateToNewProject,
),
);
}
ListView getProjectListView() {
TextStyle titleStyle = Theme.of(context).textTheme.subtitle1;
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.blue,
),
title: Text(
this.projectList[position].name,
style: titleStyle,
),
subtitle: Text(this.projectList[position].date),
onTap: () {
debugPrint('ListTile Tapped');
//navigateToDetail() einfügen
},
),
);
});
}
void _showSnackBar(BuildContext context, String message) {
final snackBar = SnackBar(
content: Text(message),
);
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void navigateToNewProject() async {
bool result = await Navigator.push(context, MaterialPageRoute(builder: (context) => NewProjectScreen()));
if (result == true) {
updateListView();
}
}
void updateListView() {
final Future<Database> dbFuture = databaseHelper.initDB();
dbFuture.then((database) {
Future<List<Project>> projectListFuture = databaseHelper.getProjectList();
projectListFuture.then((projectList) {
setState(() {
this.projectList = projectList;
this.count = projectList.length;
});
});
});
}
}
new_project_screen.dart:
import 'package:flutter/material.dart';
import 'package:leisy/db/database_helper.dart';
import 'package:leisy/model/project.dart';
import 'package:leisy/surface/main_screen.dart';
import 'package:leisy/surface/settings_screen.dart';
class NewProjectScreen extends StatefulWidget {
#override
_NewProjectScreenState createState() => _NewProjectScreenState();
}
class _NewProjectScreenState extends State<NewProjectScreen> {
Project project;
DatabaseHelper helper = DatabaseHelper();
TextEditingController nameController = TextEditingController();
TextEditingController dateController = TextEditingController();
TextEditingController locationController = TextEditingController();
#override
Widget build(BuildContext context) {
nameController.text = project.name;
dateController.text = project.date;
locationController.text = project.location;
return Scaffold(
appBar: AppBar(
title: Text("Neues Projekt"),
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context);
},
),
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Center(
child: Text(
"Menü",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 25,
),
),
),
decoration: BoxDecoration(color: Colors.blue),
),
ListTile(
leading: Icon(Icons.home),
title: Text('Home'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MainScreen()))
},
),
ListTile(
leading: Icon(Icons.add),
title: Text('Neues Projekt'),
onTap: () => {Navigator.of(context).pop()},
),
ListTile(
leading: Icon(Icons.settings),
title: Text('Einstellungen'),
onTap: () => {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => SettingsScreen()))
},
)
],
),
),
body: Padding(
padding: EdgeInsets.all(8.0),
child: ListView(
children: <Widget>[
TextField(
controller: nameController,
decoration: InputDecoration(labelText: 'Name'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateName();
});
},
),
TextField(
decoration: InputDecoration(labelText: 'Datum'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateDate();
});
},
),
TextField(
decoration: InputDecoration(labelText: 'Ort'),
style: TextStyle(fontSize: 20),
onChanged: (value) {
setState(() {
updateLocation();
});
},
),
Row(
children: <Widget>[
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColorDark),
),
child: Text('Speichern'),
onPressed: () {
setState(() {
_save();
});
},
)),
Expanded(
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(
Theme.of(context).primaryColorDark),
),
child: Text('Abbrechen'),
onPressed: () {
setState(() {
_cancel();
});
},
)),
],
)
],
)
)
);
}
void _save() async {
Navigator.pop(context, true);
await helper.insertProject(project);
}
void _showSnackBar(String message) {
SnackBar snackBar = SnackBar(content: Text(message));
ScaffoldMessenger.of(context).showSnackBar(snackBar);
}
void _cancel() async {
Navigator.pop(context, true);
_showSnackBar('Vorgang abgebrochen');
}
void updateName() {
project.name = nameController.text;
}
void updateDate() {
project.date = dateController.text;
}
void updateLocation() {
project.location = locationController.text;
}
}
project.dart:
class Project {
int _id;
String _name;
String _date;
String _location;
String _personaldb;
Project(this._name, this._date, this._location, this._personaldb);
Project.withId(
this._id, this._name, this._date, this._location, this._personaldb);
int get id => _id;
String get name => _name;
String get date => _date;
String get location => _location;
String get personalDB => _personaldb;
set name(String newName) {
if (newName.length <= 63) {
this._name = newName;
}
}
set date(String newDate) {
this._date = newDate;
}
set location(String newLocation) {
this._location = newLocation;
}
set personalDB(String newPersonalDB) {
this._personaldb = newPersonalDB;
}
Map<String, dynamic> toMap() {
var map = Map<String, dynamic>();
if (id != null) {
map['id'] = _id;
}
map['name'] = _name;
map['date'] = _date;
map['location'] = _location;
map['personalDB'] = _personaldb;
return map;
}
Project.fromMapObject(Map<String, dynamic> map) {
this._id = map['id'];
this._name = map['name'];
this._date = map['date'];
this._location = map['location'];
this._personaldb = map['personalDB'];
}
}
database_helper.dart:
import 'dart:async';
import 'dart:io';
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:leisy/model/project.dart';
class DatabaseHelper {
static DatabaseHelper _databaseHelper;
static Database _database;
String projectTable = 'project_table';
String colId = 'id';
String colName = 'name';
String colDate = 'date';
String colLocation = 'location';
String colPersonalDB = 'personalDB';
DatabaseHelper._createInstance();
factory DatabaseHelper() {
if (_databaseHelper == null) {
_databaseHelper = DatabaseHelper._createInstance();
}
return _databaseHelper;
}
Future<Database> get database async {
if (_database == null) {
_database = await initDB();
}
return _database;
}
Future<Database> initDB() async {
Directory directory = await getApplicationDocumentsDirectory();
String path = directory.path + 'projects.db';
var projectsDB = await openDatabase(path, version: 1, onCreate: _createDB);
return projectsDB;
}
void _createDB(Database db, int newVersion) async {
await db.execute('CREATE TABLE $projectTable('
'$colId INTEGER PRIMARY KEY AUTOINCREMENT,'
'$colName TEXT,'
'$colDate TEXT,'
'$colLocation TEXT,'
'$colPersonalDB TEXT)');
}
Future<List<Map<String, dynamic>>> getProjectMapList() async {
Database db = await this.database;
var result = await db.query(projectTable);
return result;
}
Future<int> insertProject(Project project) async {
Database db = await this.database;
var result = await db.insert(projectTable, project.toMap());
return result;
}
Future<int> updateProject(Project project) async {
var db = await this.database;
var result = await db.update(projectTable, project.toMap(), where: '$colId = ?', whereArgs: [project.id]);
return result;
}
Future<int> deleteProject(int id) async {
var db = await this.database;
int result = await db.delete(projectTable, where: '$colId = $id');
return result;
}
Future<int> getCount() async {
Database db = await this.database;
List<Map<String, dynamic>> x = await db.rawQuery('SELECT COUNT (*) from $projectTable');
int result = Sqflite.firstIntValue(x);
return result;
}
Future<List<Project>> getProjectList() async {
var projectMapList = await getProjectMapList();
int count = projectMapList.length;
List<Project> projectList = <Project>[];
for (int i = 0; i < count; i++) {
projectList.add(Project.fromMapObject(projectMapList[i]));
}
return projectList;
}
}
Error:
======== Exception caught by widgets library =======================================================
The following NoSuchMethodError was thrown building NewProjectScreen(dirty, state: _NewProjectScreenState#670bc):
The getter 'name' was called on null.
Receiver: null
Tried calling: name
The relevant error-causing widget was:
NewProjectScreen file:///C:/Users/gabri/AndroidStudioProjects/leisy/lib/surface/main_screen.dart:116:89
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _NewProjectScreenState.build (package:leisy/surface/new_project_screen.dart:24:35)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4612:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4495:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4667:11)
...
====================================================================================================
If anybody can help me, I would really appreciate it. And if anything in my code is inconvenient or badly implemented, please be kind with me I'm a beginner at this.
The file new_project_screen.dart has the problem
To be exact, the problem can be found in lines 24:35
And seems like that project variable is null project.name;
That is because you are creating Project project but isn't instancied yet. Is just a null variable
See the image below, will help you to understand a bit:
https://dartpad.dev/1ebc897cd3f547cc0b79e52290a63653
So to fix it, you need to create the instance previously

Why there is no list records returning in this flutter code application?

I'm receiving the following error while trying to display a user's all appointments with their corresponding date and title from databse. Can anyone please point out how to fix it?(Solved!)
Issue: Why there is no list records returning in this flutter code application?
Here is the code:
import 'package:flutter/material.dart';
import 'package:frontend/main.dart';
import 'package:frontend/util/authentication.dart';
import 'package:frontend/util/serverDetails.dart';
import 'package:http/http.dart' as http;
import 'package:frontend/components/appointment.dart';
import 'package:frontend/screens/appointmentdetail.dart';
import 'dart:convert';
import 'package:intl/intl.dart';
import 'package:frontend/screens/appointments.dart';
import 'package:table_calendar/table_calendar.dart';
class AppointmentList extends StatefulWidget {
#override
_AppointmentListState createState() => _AppointmentListState();
}
class _AppointmentListState extends State<AppointmentList>
with TickerProviderStateMixin {
Map<DateTime, List> _events;
List _selectedEvents;
#override
void initState() {
super.initState();
_events = Map<DateTime, List>();
getAppointments();
}
getAppointments() async {
String currentToken = await Authentication.getCurrentToken();
print(currentToken);
if (currentToken == null) {
print('bouncing');
Authentication.bounceUser(context);
} else {
String auth = "Bearer " + currentToken;
String url = ServerDetails.ip +
':' +
ServerDetails.port +
ServerDetails.api +
'me/appointments';
print(url);
Map<String, String> headers = {"Authorization": auth};
print(headers);
var jsonResponse = null;
var response = await http.get(url, headers: headers);
print(response.body);
if (response.statusCode == 200) {
print("200" + response.body);
jsonResponse = json.decode(response.body);
if (jsonResponse != null) {
setState(() {
for (var doc in jsonResponse) {
Appointment temp = Appointment.fromJson(doc);
print("TEMP" + temp.date.toString());
//print("TEMP" + temp.duration.toString());
if (_events[temp.date] == null) {
print("deb1" + temp.date.toString());
_events[temp.date] = List()..add(temp);
} else {
//_events[temp.date] = List()..add(temp);
_events[temp.date].add(temp);
}
}
});
}
} else {
print(response.body);
}
}
}
void _allDataSelected(DateTime day, List events) {
print('CALLBACK: _allDaySelected');
setState(() {
_selectedEvents = events;
});
}
#override
build(context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(60.0),
child: AppBar(
leading: new IconButton(
icon: new Icon(Icons.arrow_back),
color: Colors.black,
onPressed: () {
setState(() {});
Navigator.push(context,
MaterialPageRoute(builder: (context) => MainPage()));
}),
centerTitle: true,
title: Text("Appointment", style: TextStyle(color: Colors.black)),
backgroundColor: Colors.white,
brightness: Brightness.light,
// backgroundColor: Color(0x44000000),
elevation: 0.5,
actions: <Widget>[
IconButton(
color: Colors.black,
icon: Icon(Icons.calendar_view_day),
onPressed: () {
setState(() {});
Navigator.push(context,
MaterialPageRoute(builder: (context) => Appointments()));
},
)
],
),
),
body: ListView(
children: _selectedEvents
.map((event) => Container(
decoration: BoxDecoration(
border: Border.all(width: 0.8),
borderRadius: BorderRadius.circular(12.0),
),
margin: const EdgeInsets.symmetric(
horizontal: 8.0, vertical: 4.0),
child: (event is Appointment)
? ListTile(
leading: Column(children: <Widget>[
//Show Weekday, Month and day of Appiontment
Text(
DateFormat('EE').format(event.date) +
' ' +
DateFormat.MMMd().format(event.date),
style: TextStyle(
color: Colors.blue.withOpacity(1.0),
fontWeight: FontWeight.bold,
)),
//Show Start Time of Appointment
Text(DateFormat.jm().format(event.date),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: FontWeight.bold,
height: 1.5,
)),
//Show End Time of Appointment
Text(
DateFormat.jm().format(event.date.add(
Duration(minutes: event.duration ?? 0))),
style: TextStyle(
color: Colors.black.withOpacity(0.6)),
),
]), //Text(DateFormat.Hm().format(event.date)),//DateFormat.Hm().format(now)
title: Text(event.title),
trailing: event.status == 'UNCONFIRMED'
? Column(children: <Widget>[
//event.status=='CONFIRMED' ?
Icon(Icons.error,
color: Colors.pink,
//size:25.0,
semanticLabel:
'Unconfirmed Appointment'), //:Container(width:0,height:0),
Icon(Icons.arrow_right),
])
: Icon(Icons.arrow_right),
onTap: () {
setState(() {});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
AppointmentDetail(event)));
},
)
: null))
.toList()));
}
}
Another part of code for appointment.dart, which shows how that appointment looks like:
import 'package:flutter/foundation.dart';
class Appointment {
final String id;
final String pid;
final String title;
final String detail;
final DateTime date;
final int duration;
final String note;
final String userNote;
final String status;
var doctor;
Appointment(
{this.id,
this.pid,
this.title,
this.detail,
this.date,
this.duration,
this.note,
this.userNote,
this.status});
factory Appointment.fromJson(Map<String, dynamic> json) {
return Appointment(
id: json['id'],
pid: json['uid'],
title: json['title'],
detail: json['detail'],
date: DateTime.parse(json['date']),
duration: json['duration'] as int,
note: json['note'],
userNote: json['user_note'],
status: json['status']);
}
}
Here is the expected outcomes:
enter image description here
Here is the new outcomes: (should have the expected outcomes below the 'Appointment'title)
enter image description here
Here is the update code:
#override
void initState() {
super.initState();
_events = Map<DateTime, List>();
getAppointments().then((result) {
print("result:$result");
setState(() {});
});
}
Here is the console output:
enter image description here
In your code _selectedEvents is null, it is not initialized. Code which uses the _selectedEvents variable is _allDataSelected() method which isn't called.
It's a good practice to initialize the variables like this:
List _selectedEvents = [];