Expected a value of type 'String', but got one of type 'Null' StreamBuilder<QuerySnapshot<Object?>> - flutter

I trying create a contact list to be displayed on my screen as a user edit of delete his details. I got this error and UI doesn't show anything. The error is : Expected a value of type 'String', but got one of type 'Null'
here is where error happens:
---dart
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
class contactlist extends StatefulWidget {
const contactlist({ Key? key }) : super(key: key);
#override
State<contactlist> createState() => _contactlistState();
}
class _contactlistState extends State<contactlist> {
final Stream<QuerySnapshot>_myUserContacts =
FirebaseFirestore.instance.collection('userContact').snapshots();
#override
Widget build(BuildContext context) {
TextEditingController _nameFieldcntroler = TextEditingController();
TextEditingController _phoneNumFieldcntroler = TextEditingController();
TextEditingController _EmailFieldcntroler = TextEditingController();
TextEditingController _AgeFieldcntroler = TextEditingController();
void _delete(docId){
FirebaseFirestore.instance
.collection("userContact")
.doc(docId)
.delete()
.then((value) => print("deleted"));
}
void _update(data){
var collection = FirebaseFirestore.instance.collection("userContact");
_nameFieldcntroler.text = data["names"];
_phoneNumFieldcntroler.text = data["phoneNumber"];
_EmailFieldcntroler.text = data["email"];
_AgeFieldcntroler.text = data["age"];
showDialog(context: context,
builder: (_) => AlertDialog(
title: Text("Update"),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextField(
controller:_nameFieldcntroler,
),
TextField(
controller:_phoneNumFieldcntroler,
),
TextField(
controller:_EmailFieldcntroler,
),
TextField(
controller:_AgeFieldcntroler,
),
TextButton(
onPressed: (){
collection.doc(data["doc_Id"])
.update({
"names": _nameFieldcntroler.text,
"phoneNumber": _phoneNumFieldcntroler.text,
"email": _EmailFieldcntroler.text,
"age": _AgeFieldcntroler.text,
});
Navigator.pop(context);
},
child: Text("Update")),
]),
)
);
}
return StreamBuilder(
stream: _myUserContacts,
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot<Object?>> snapshot){
if (snapshot.hasError){
return const Text("Something went wrong");
}
if(snapshot.connectionState == ConnectionState.waiting){
return const Center(child: CircularProgressIndicator());
}
if(snapshot.hasData){
return Row(
children: [
Expanded(
child: SizedBox(
height: (MediaQuery.of(context).size.height),
width: (MediaQuery.of(context).size.width),
child: ListView(
children: snapshot.data!.docs
.map((DocumentSnapshot documentSnapshot) {
Map<String, dynamic> data = documentSnapshot.data()! as Map<
String, dynamic>;
return Column(
children: [
Card(
child: Column(
children:[
ListTile(
title: Text(data['names']),
subtitle:Text(data['phoneNumber']),
),
ButtonTheme(
child: ButtonBar(
children:[
OutlineButton.icon(
onPressed:(){
_update(data);
},
icon: Icon(Icons.edit),
label: Text("Edit"),
),
OutlineButton.icon(
onPressed:(){
_delete(data["doc_Id"]);
},
icon: Icon(Icons.remove),
label: Text("Delete"),
)
],
),
),
],
)
)
],
);
}).toList(),
),
)
)
],
);
}else{
return(Text("No data"));
}
},
);
}
}
---dart
---dart
The following TypeErrorImpl was thrown building StreamBuilder<QuerySnapshot<Object?>>(dirty, dependencies: [MediaQuery], state: _StreamBuilderBaseState<QuerySnapshot<Object?>, AsyncSnapshot<QuerySnapshot<Object?>>>#1efa0):
Expected a value of type 'String', but got one of type 'Null'
The relevant error-causing widget was
StreamBuilder<QuerySnapshot<Object?>>
---dart

Related

The following assertion was thrown building StreamBuilder<QuerySnapshot<Object?>>: setState() or markNeedsBuild() called during build

This Overlay widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: Overlay-[LabeledGlobalKey<OverlayState>#9cc87]
state: OverlayState#c130e(entries: [OverlayEntry#b04b5(opaque: true; maintainState: false), OverlayEntry#67dea(opaque: false; maintainState: true), OverlayEntry#fed19(opaque: false; maintainState: false), OverlayEntry#d834c(opaque: false; maintainState: true)])
The widget which was currently being built when the offending call was made was: StreamBuilder<QuerySnapshot<Object?>>
dirty
dependencies: [_LocalizationsScope-[GlobalKey#76036]]
state: _StreamBuilderBaseState<QuerySnapshot<Object?>, AsyncSnapshot<QuerySnapshot<Object?>>>#15351
The relevant error-causing widget was:
StreamBuilder<QuerySnapshot<Object?>> StreamBuilder:file:///C:/Users/Administrator/StudioProjects/selam/lib/screens/notes.dart:50:15
notes page:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:selam/constants.dart';
import 'package:selam/screens/noteEditor.dart';
import 'package:selam/screens/notesReader.dart';
import 'package:selam/widget/notesCard.dart';
class Notes extends StatefulWidget {
#override
State<Notes> createState() => _NotesState();
}
class _NotesState extends State<Notes> {
final _firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
User? loggedInUser = FirebaseAuth.instance.currentUser;
void getCurrentUser() async {
try {
final user = _auth.currentUser;
if (user != null) {
loggedInUser = user;
}
} catch (e) {}
}
#override
void initState() {
super.initState();
getCurrentUser();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kColor2,
body: Padding(
padding: EdgeInsets.only(right: 10, left: 10, top: 15),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Center(
child: Text(
'Your Notes',
style: kheaderTextStyle,
)),
StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('/notes/users/savedNotes')
.snapshots(),
builder: (context, snapshots) {
if (snapshots.connectionState == ConnectionState.waiting) {
showDialog(
context: context,
builder: (context) {
return Center(
child: SpinKitCircle(
size: 125,
itemBuilder: (context, index) {
final colors = [
Color(0xFF091304),
Color(0xFF0b1806),
Color(0xFF0f2208),
Color(0xFF142b0a),
Color(0xFF16300b),
Color(0xFF2d4523),
Color(0xFF45593c),
Color(0xFF5c6e54),
Color(0xFF73836d),
Color(0xFF8b9885),
Color(0xFFa2ac9d),
Color(0xFFb9c1b6)
];
final color = colors[index % colors.length];
return DecoratedBox(
decoration: BoxDecoration(
color: color, shape: BoxShape.circle));
},
));
});
}
if (snapshots.hasData) {
return GridView(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2),
children: snapshots.data!.docs
.map(
(note) => NoteCard(
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => NotesReader(note)));
},
doc: note,
),
)
.toList(),
);
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
'No notes',
style: ktextFieldTextStyle,
),
Text('Tap the Add button to create a note.')
],
),
);
},
),
],
),
),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => NoteEditor()),
);
},
backgroundColor: kColor2,
foregroundColor: kColor1,
label: Text('Add Note'),
icon: Icon(Icons.edit_note),
),
);
}
}
the above page is called in homepage() in 3rd tab:
body: TabBarView(
controller: _controller,
children: [
Icon(Icons.home),
ChatScreen(),
Notes(),
Icon(Icons.videocam_outlined),
UserProfile(),
],
),
I just want to know where my error is. Also all buttons aren't working on the notes page.

How can i separate the selected item on a DropDownButton?

Right now I'm trying to make a dialog where I can change the role for the users that has been logged in on my app, for that i have a ListView with Cards that shows up the information of the user and a DropDownButton to select the role that a can assign to that user.
But when i select a role or item it change on all the user's Card.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
final user = FirebaseAuth.instance.currentUser!;
String role = '1';
Stream<QuerySnapshot> readUsers() =>
FirebaseFirestore.instance.collection('users').snapshots();
Future accDialog(BuildContext context) => showDialog(
context: context,
builder: (context) => StatefulBuilder(
builder: (BuildContext context, setState) => Dialog(
child: Container(
margin: const EdgeInsets.all(24),
child: StreamBuilder(
stream: readUsers(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
roleFunction(String q) {
setState(() {
role = q;
});
}
if (snapshot.hasError) {
return const Text('Algo ha salido mal!');
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Text("Cargando");
}
return ListView(
shrinkWrap: true,
children: snapshot.data!.docs
.map((DocumentSnapshot document) {
Map<String, dynamic> data =
document.data()! as Map<String, dynamic>;
return Card(
margin: const EdgeInsets.all(8),
child: Padding(
padding: const EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
data['name'],
style:
Theme.of(context).textTheme.titleMedium,
),
Text('Correo: ${data['email']}'),
Text('Rol Actual: ${data['role']}'),
Row(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: RoleMenu(
roleFunction: roleFunction)),
const Spacer(),
ElevatedButton(
onPressed: () {
final setRole = <String, String>{
"role": role,
};
FirebaseFirestore.instance
.collection('users')
.doc(document.id)
.set(setRole,
SetOptions(merge: true));
},
child: const Text('Guardar'))
],
)
],
),
),
);
})
.toList()
.cast(),
);
},
),
),
),
),
);
class RoleMenu extends StatefulWidget {
final Function roleFunction;
const RoleMenu({super.key, required this.roleFunction});
#override
State<RoleMenu> createState() => _RoleMenuState();
}
class _RoleMenuState extends State<RoleMenu> {
String selected = '';
#override
Widget build(BuildContext context) {
return DropdownButtonHideUnderline(
child: DropdownButton<String>(
enableFeedback: true,
dropdownColor: ElevationOverlay.applySurfaceTint(
Theme.of(context).colorScheme.surface,
Theme.of(context).colorScheme.surfaceTint,
2),
iconEnabledColor: Theme.of(context).colorScheme.onSurfaceVariant,
style: Theme.of(context).textTheme.labelLarge,
items: const [
DropdownMenuItem<String>(
value: 'User',
child: Text('Usuario'),
),
DropdownMenuItem<String>(
value: 'Admin',
child: Text('Admin'),
),
],
value: selected,
onChanged: (value) {
setState(() {
selected = value!;
widget.roleFunction(selected);
});
},
),
);
}
}

Flutter error : 'isDocument()': is not true

I am making a chat detail page using flutter. However, I am getting this error in the stream part. I don't have much experience with flutter. I couldn't solve it for 2 days.
Error :
Exception has occurred.
_AssertionError ('package:cloud_firestore_platform_interface/src/internal/pointer.dart': Failed assertion: line 56 pos 12: 'isDocument()': is not true.)
Code :
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_bubble/bubble_type.dart';
import 'package:flutter_chat_bubble/chat_bubble.dart';
import 'package:flutter_chat_bubble/clippers/chat_bubble_clipper_6.dart';
class Chat extends StatefulWidget {
Chat({super.key, required this.friendUid, required this.friendName});
final String friendUid;
final String friendName;
#override
State<Chat> createState() => _ChatState(friendUid, friendName);
}
class _ChatState extends State<Chat> {
CollectionReference chats = FirebaseFirestore.instance.collection("chats");
final friendUid;
final friendName;
final currentUserUid = FirebaseAuth.instance.currentUser!.uid;
var chatDocId;
var _controller = TextEditingController();
_ChatState(this.friendName, this.friendUid);
#override
void initState() {
chats
.where("users", isEqualTo: {friendUid: null, currentUserUid: null})
.limit(1)
.get()
.then(
(QuerySnapshot snapshotx) {
if (snapshotx.docs.isNotEmpty) {
chatDocId = snapshotx.docs.single.id;
} else {
chats.add({
"users": {currentUserUid: null, friendUid: null},
}).then((value) {
chatDocId = value;
});
}
},
)
.catchError(() {});
super.initState();
}
void sendMessage(String msg) {
if (msg == "") return;
chats.doc(chatDocId.toString()).collection("messages").add({
"createdOn": FieldValue.serverTimestamp(),
"uid": currentUserUid,
"msg": msg
}).then((value) {
_controller.text = "";
});
}
bool isSender(String friend) {
return friend == currentUserUid;
}
Alignment getAlignment(String friend) {
if (friend == currentUserUid) {
return Alignment.topRight;
}
return Alignment.topLeft;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("chat")),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Expanded(
child: StreamBuilder<QuerySnapshot>(
stream: chats
.doc(chatDocId.toString())
.collection("messages") ==> the error part
.orderBy("createdOn", descending: true)
.snapshots(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return const Center(
child: Text("Error"),
);
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasData) {
return ListView(
reverse: true,
children: snapshot.data!.docs
.map((DocumentSnapshot documentSnapshot) {
Map<String, dynamic> data = documentSnapshot
.data() as Map<String, dynamic>;
return ChatBubble(
clipper: ChatBubbleClipper6(
nipSize: 0,
radius: 0,
type: isSender(data["uid"].toString())
? BubbleType.sendBubble
: BubbleType.receiverBubble),
alignment:
getAlignment(data["uid"].toString()),
margin: EdgeInsets.only(top: 20),
backGroundColor:
isSender(data["uid"].toString())
? Color(0xFF08C187)
: Color(0xffE7E7ED),
child: Container(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context)
.size
.width *
0.7),
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(
data["msg"],
style: TextStyle(
color: isSender(
data["uid"]
.toString())
? Colors.white
: Colors.black),
maxLines: 100,
overflow:
TextOverflow.ellipsis,
)
],
)
],
)),
);
}).toList());
}
return Container(
width: 300,
height: 300,
color: Colors.grey,
);
})),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(
child: TextField(
controller: _controller,
)),
IconButton(
onPressed: () {
sendMessage(_controller.text);
},
icon: Icon(Icons.send))
],
)
],
),
));
}
}
Can you help me. Thank you.

Pass items to a list to previous screen in Flutter

I have a search page that displays names with an add icon. When I press the add icon I want to pass the name to my previous screen that displays a list with names. I tried to do it as you can see down in my code but I have an error that my Athlete model doesn't have the constructor add. Can you help me figure out how to display the names in my list in previous screen? Thanks in advance!
My first screen that I display a list with names:
class AthleteScreen extends StatefulWidget {
const AthleteScreen({Key? key}) : super(key: key);
#override
State<AthleteScreen> createState() => _AthleteScreenState();
}
class _AthleteScreenState extends State<AthleteScreen> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Future<List<Athlete>>? futureAthletebyTeamKey;
final List<Athlete> _athlete = [];
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
const Text(
'Athletes'),
actions: <Widget>[
Row(
children: [
IconButton(
onPressed: () {
Navigator.of(context)
.push<Athlete>(
MaterialPageRoute(builder: (_) => const AddAthlete()))
.then((value) => setState(() {
if (value != null && value is Athlete) {
Athlete.add(_athlete[index].lastName, _athlete[index].firstName,_athlete[index].fatherName); //here is when I push to the page where the names that I want to add are displayed
}
}));
},
icon: const Icon(Icons.add),
color: Colors.black,
iconSize: 30.0,
),
],
),
],
),
body: Stack(
children: [
SingleChildScrollView(
child: Column(children: [
FutureBuilder<List<Athlete>>(
future: futureAthletebyTeamKey,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Athlete> _athlete = snapshot.data;
return ListView.builder(
itemCount: _athlete.length,
itemBuilder: (BuildContext context, int i) {
return CheckboxListTile(
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Flexible(
child: Text(
'${_athlete[i].lastName} ${_athlete[i].firstName}',
),
),
],
),
} else if (snapshot.hasError) {
logger.e('${snapshot.error}');
}
return const Center(
heightFactor: 20,
child: CircularProgressIndicator.adaptive(),
);
},
),
]),
),
);
}
}
My second screen where the names that I want to add in the list of my first page are displayed
class AddAthlete extends StatefulWidget {
const AddAthlete({Key? key}) : super(key: key);
#override
State<AddAthlete> createState() => _AddAthleteState();
}
class _AddAthleteState extends State<AddAthlete> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
Future<List<Athlete>>? futureSearchAthleteByName;
#override
void initState() {
futureSearchAthleteByName =
ApiService.searchAthletesByName(context) as Future<List<Athlete>>?;
text = myController.text;
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Text(
'Add Athletes',
),
],
),
),
body: SingleChildScrollView(
child: Column(
children: [
Stack(
children: [
SingleChildScrollView(
child: Column(children: [
FutureBuilder<List<Athlete>>(
future: futureSearchAthleteByName,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
List<Athlete> _athlete = snapshot.data;
return ListView.builder(
itemCount: _athlete.length,
itemBuilder: (BuildContext context, int index) {
if (myController.text == '') {
return Container();
} else if (myController.text != '' &&
_athlete[index]
.lastName!
.toLowerCase()
.contains(myController.text
.toLowerCase()) ||
_athlete[index]
.firstName!
.toLowerCase()
.contains(
myController.text.toLowerCase())) {
return Column(
children: [
ListTile(
title: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
),
Row(
children: [
Flexible(
child: Text(
'${_athlete[index].lastName} ${_athlete[index].firstName}',
),
),
],
),
Row(
children: [
Flexible(
child: Text(
'(${_athlete[index].fatherName})',
),
),
],
),
],
),
trailing: IconButton(
icon: const Icon(
Icons.add,
color: Colors.black,
),
onPressed: () {
Navigator.pop(
context,
Athlete(
lastName: _athlete[index]
.lastName,
firstName: _athlete[index]
.firstName,
fatherName: _athlete[index]
.fatherName));
print(_athlete[index].lastName);
print(_athlete[index].firstName);
print(_athlete[index].fatherName); \\here is when I pop the names in my previous screen
},
),
),
],
);
}
});
} else if (snapshot.hasError) {
logger.e('${snapshot.error}');
}
return Container();
},
),
]),
),
],
),
],
),
),
);
}
}
If I was you I might do it in a different way
I add all the user id to the list on the second screen and pass the list to the second screen
in the first screen I call the API and get all the data by id and show it
(when a user doesn't select any element don't call the API)

error: The argument type 'Null' can't be assigned to the parameter type 'Map<String, dynamic>'

I am writing my first Flutter App with some online tutorials and I found error that I can't fix it.
I am trying to add Navigation by Navigator, but I can't understand why it doesn't work.
Once I am using Navigator in GestureDetector and it works fine, but I don't know what I supposed to do in floatingActionButton to make it work the same way. Note(NoteMode.Adding, null) probably should be something else instead null, because this null is making error (error from title). Can someone explain me what I am doing wrong and what I don't undarstand
Note List
#override
_NoteListState createState(){return _NoteListState();}
}
class _NoteListState extends State<NoteList> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Notes"),
),
body: FutureBuilder(
future: NoteProvider.getNoteList(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
final notes = snapshot.data;
return ListView.builder(
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) =>
Note(NoteMode.Editing, (notes as dynamic)[index]))
);
},
child: Card(
child: Padding(
padding: const EdgeInsets.only(
top: 30.0, bottom: 30.0, left: 13, right: 22),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
_NoteTitle((notes as dynamic)[index]['title']),
Container(height: 3,),
_NoteText((notes as dynamic)[index]['text']),
],
),
),
),
);
},
itemCount: notes.length,
);
}
return Center(child: CircularProgressIndicator());
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => Note(NoteMode.Adding, null)));
},
child: Icon(Icons.add),
),
);
}
}
Note
enum NoteMode{
Editing,
Adding
}
class Note extends StatefulWidget{
final NoteMode noteMode;
final Map<String, dynamic> note;
Note(this.noteMode, this.note,);
#override
State<Note> createState() => _NoteState();
}
class _NoteState extends State<Note> {
final TextEditingController _titleController = TextEditingController();
final TextEditingController _textController = TextEditingController();
List<Map<String, String>> get _notes => NoteInheritedWidget.of(context).notes;
#override
void didChangeDependencies(){
if(widget.noteMode == NoteMode.Editing){
_titleController.text = widget.note['title'];
_textController.text = widget.note['text'];
}
super.didChangeDependencies();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
widget.noteMode == NoteMode.Adding ? 'Add note' : 'Edit note',
),
),
body: Padding(
padding: const EdgeInsets.all(40.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
controller: _titleController,
decoration: InputDecoration(
hintText: "Note title",
),
),
Container(height: 8,),
TextField(
controller: _textController,
decoration: InputDecoration(
hintText: "Note text",
),
),
Container(height: 15,),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_NoteButton('SAVE', Colors.lightBlue, (){
final title = _titleController.text;
final text = _textController.text;
if(widget.noteMode == NoteMode.Adding){
NoteProvider.insertNote({
'title': title,
'text': text
});
} else if (widget.noteMode == NoteMode.Editing){
NoteProvider.updateNote( {
'id': widget.note['id'],
'title': _titleController.text,
'text': _textController.text,
});
}
Navigator.pop(context);}),
_NoteButton('DISCARD', Colors.grey, (){Navigator.pop(context);}),
widget.noteMode == NoteMode.Editing ?
_NoteButton('DELETE', Colors.redAccent, () async {
await NoteProvider.deleteNote(widget.note['id']);
Navigator.pop(context);})
: Container(),
],
)
],
),
),
);
}
}
Either you have to pass Map in place of null because you are receiving a Map on that page
Navigator.push(context, MaterialPageRoute(builder: (context) => Note(NoteMode.Adding, {"key":"value"})));
or you have to make Map nullable as
class Note extends StatefulWidget{
final NoteMode noteMode;
final Map<String, dynamic>? note;
Note(this.noteMode, this.note,);
#override
State<Note> createState() => _NoteState();
}