How do I use my custom widget Notes? I unfortunately can't use the full code in the AddNoteScreen.
I got this error when I changed a few things from the class I'm taking. Below I've pasted the instructors code, with my custom widget included. I'll comment below with the other changes I tried that lead me to this error.
Custom widget down to bare bones:
class Notes extends StatelessWidget {
TextEditingController notesController = TextEditingController();
@override
Widget build(BuildContext context) {
return TextField(
controller: notesController,
);
}
}
class AddNoteScreen extends StatefulWidget {
User user;
AddNoteScreen({
required this.user,
});
@override
State<AddNoteScreen> createState() => _AddNoteScreenState();
}
class _AddNoteScreenState extends State<AddNoteScreen> {
TextEditingController titleController = TextEditingController();
TextEditingController notesController = TextEditingController();
bool loading = false;
@override
void initState(){
super.initState(
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor:Color (0xFF162242),
elevation: 0,
),
body: GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
new TextEditingController().clear();
},
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(20),
child: Column(children: [
Text("Title", style: TextStyle(
color: Colors.white,
),
),
SizedBox(
height: 15,
),
Container(
height: 60,
color: Colors.white,
child: TextField(
style: TextStyle(
color: Color(0xFF192A4F),
),
controller: titleController,
),
),
Notes(), // My Custom Widget
SizedBox(height: 50,),
loading ? Center (child: CircularProgressIndicator(),) : Container(
height: 50,
width: MediaQuery.of(context).size.width,
child: ElevatedButton(
onPressed: ()async{
if (
titleController.text == "" || notesController.text == "") // HERE
{
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text("All fields are required")));
} else {
setState(() {
loading = true;
});
await FirestoreService().insertNote(titleController.text, notesController.text, widget.user.uid); // HERE
setState(() {
loading = false;
});
Navigator.pop(context);
}
}, child: Text("Add Note"),
),),
]),),
),
),
);
}
}
^ above I changed notesController.text == ""
to Notes == ""
and then notesController.text
to Notes()
class FirestoreService{
FirebaseFirestore firestore = FirebaseFirestore.instance;
Future insertNote(String title, String notes, String userId)async{
try{
await firestore.collection('notes').add({
"title":title,
"notes":notes,
"userId": userId
});
} catch (e) {}
}
}
^ above I changed String
to Widget
for notes
class NoteModel {
String id;
String title;
String notes;
String userId;
NoteModel({
required this.id,
required this.title,
required this.notes,
required this.userId
});
factory NoteModel.fromJson(DocumentSnapshot snapshot){
return NoteModel(
id: snapshot.id,
title: snapshot['title'],
notes: snapshot['notes'],
userId: snapshot['userId']
);
}
}
^ above I changed String
to Widget
for notes
class HomeScreen extends StatefulWidget {
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final user = FirebaseAuth.instance.currentUser!;
FirebaseFirestore firestore = FirebaseFirestore.instance;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Notes'),
centerTitle: true,
backgroundColor: Color (0xFF162242),
actions: [
TextButton(onPressed: () => FirebaseAuth.instance.signOut(), child: Text("Sign Out", style: TextStyle(color: Colors.white),),),
],
),
body: StreamBuilder(
stream: FirebaseFirestore.instance.collection("notes").where('userId', isEqualTo: user.uid).snapshots(),
builder: (context, AsyncSnapshot snapshot){
if (snapshot.hasData){
if(snapshot.data.docs.length > 0){
return ListView.builder(
itemCount: snapshot.data.docs.length,
itemBuilder: (context,index) {
NoteModel note = NoteModel.fromJson(snapshot.data.docs[index]);
return Card(
margin: EdgeInsets.only(top: 16, left: 10, right: 10, bottom: 16),
child: Column(
children: [
ListTile(
title: Center(child: Text(note.title, style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
),
),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => EditNoteScreen(),));},
),
ListTile(title: Center(child:
Container(
height: 300,
child:
Text(note.notes),),), // HERE
),
]),
);
}
);
}else Center(child: Text("No notes available", style: TextStyle(color: Colors.white),),);
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircularProgressIndicator(),
],
),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => AddNoteScreen(user: user)));
},
backgroundColor: Color (0xFF162242),
child: Icon(Icons.add),
),
);
}
}
^ Text(note.notes)
is where I get the error.
I don't really know what I'm doing but can something like this work ? Totally different answer is okay too!
I'm sorry that's a lot of code. Any help is appreciated. Also link to the class if anyone is interested https://skl.sh/3wxeMVF
CodePudding user response:
Assumptions
Based on the code and comments I guess the actual class NoteModel
and Notes
are looking something like this:
class NoteModel {
Notes notes;
...
}
class Notes extends StatelessWidget {
TextEditingController notesController = TextEditingController();
...
}
Problem
This explains the error message The argument type ‘Widget’ can’t be assigned to the parameter type ‘String’?
:
Text(note.notes)
expects note.notes
to be a String. Whereas you changed note.notes
to be the Widget Notes
.
Solution 1
The widget Text()
expects Strings, not another Widget. Thus,
change notes
back to a String:
class NoteModel {
String notes;
...
}
Build the rest of your code around this NoteModel
, do not change it.
Solution 2
If you want to use
class NoteModel {
Notes notes;
...
}
then the Text widget would be called something like this:
Text(note.notes.notesController.text)
However, this is NOT recommended, as a NoteModel
is a data model. And data models should never hold Widgets. A Widget is meant for showing data, not for holding it. A data model and a Widget serve different functions. Keep them separated.
Firebase
Note, that one cannot store whole Widgets (like Notes
) in in Firebase but only Strings, Numbers etc.
(Please always post your current code, not code that is indirectly related related to the issue. Otherwise, people will find it very difficult to spot the problem.)