The argument type ‘Widget’ can’t be assigned to the parameter type ‘String’? - firebase

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

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.)

Related

How to initialize a QuerySnapshot type variable for a 1 document request to FireBase / Firestore with Flutter?

I'm trying to get documents from a collection with the method FireBaseFirestore.instance.collection("users").where("name", isEqualTo : "something").get() which used to have a return type of QuerySnapshot.
My goal is to make a ListView or anything that can display like a ListView the result(s) of this request.
I have these functions :
This one is to get the documents with the where method
class DataBaseMeth {
getUserByUsername(String username) async{
return fsInstance.collection("users").where("name", isEqualTo: username).get();
}
}
This one is the widget with the result :
class SearchResultTile extends StatelessWidget {
final String username;
const SearchResultTile({
Key? key,
required this.username,
}) : super(key: key);
#override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 25.0),
child: Row(
children: [
Column(
children: [
Text(
username,
),//username
],
),
)
],
),
);
}
}
And finally the class of the page :
class SearchPage extends StatefulWidget {...}
class _SearchPageState extends State<SearchPage> {
DataBaseMeth dataBaseMethods = DataBaseMeth();
TextEditingController usernameSearchController = TextEditingController();
QuerySnapshot searchSnapshot; //the only way the code run is to replace the type by dynamic
initSearch(){
dataBaseMethods.getUserByUsername(usernameSearchController.text)
.then((result){
setState((){
searchSnapshot = result;
print("result : $searchSnapshot");
//print("result : ${searchSnapshot.docs[1].data.toString()}");
});
});
}
Widget searchList(){
return searchSnapshot != null ?
ListView.builder(
shrinkWrap: true,
itemCount: searchSnapshot.docs.length,
itemBuilder: (context, index) {
return SearchResultTile(
username: searchSnapshot.docs[index].data.toString(),
personalMessage: "personalMessage");
}
)
:
Container();
}
#override
void initState() {
searchList();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: const MainAppBar(titleText: 'Search truc', mainPage: true),
body: Container(
padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0),
child: Column(
children: [
Row(
children: [
Expanded(
child: TextField(
controller: usernameSearchController,
decoration: textFieldInputDecoration("search username..."),
style: whiteText(),
),
),
IconButton(
onPressed: () {
initSearch();
},
icon: const Icon(Icons.search_outlined),
color: const Color(0xFFFFFFFF),
highlightColor: Colors.deepPurple,
splashColor: const Color(0xFF3A206B),
tooltip: "Search",
),
],
),
searchList()
],
),
),
);
}
}
The result of the print of searchSnapshot (when I put it on dynamic) is :
I/flutter (31401): result : Instance of '_JsonQuerySnapshot'
And nothing appears when I tap on the button.
Your fsInstance.collection("users").where("name", isEqualTo: username).get() returns a Future<QuerySnapshot> not a QuerySnapshot, so that's why you can't assign it to QuerySnapshot searchSnapshot. You can assign it to Future<QuerySnapshot> searchSnapshot though.
That also means that if you want to use it in your UI you'll have to either wrap it in a FutureBuilder or pass it to setState().

The argument type 'UserResult' can't be assigned to the parameter type 'UserSearch'

I am trying to make a search functionality that will help a user search for another user. I have created a stateful widget UserSearch and a stateless Widget UserResult. UserSearch builds the results based on UserResult's data. However I am unable to pass UserResult as an argument in UserSearch and I have no clue why. Any help will be great. Thanks in advance
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:vibing_app/feed.dart';
import 'package:vibing_app/model/user.dart';
class UserSearch extends StatefulWidget {
#override
_UserSearchState createState() => _UserSearchState();
}
class _UserSearchState extends State<UserSearch> {
final userRef = FirebaseFirestore.instance.collection('user');
TextEditingController searchController = new TextEditingController();
Future<QuerySnapshot> searchResults;
handleSearch(String query)
{
Future<QuerySnapshot> users = userRef.where("first_name"+ "last_name", isGreaterThanOrEqualTo: query).get();
setState(() {
searchResults = users;
});
}
clearSearch()
{
searchController.clear();
}
AppBar buildSearchField()
{
return AppBar(
backgroundColor: Colors.yellow,
title: TextFormField(
controller: searchController,
decoration: InputDecoration(
hintText: "Search for a user",
filled: true,
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: clearSearch,
),
),
onFieldSubmitted: handleSearch,
),
);
}
Container searchContainer(){
final Orientation orientation = MediaQuery.of(context).orientation;
return Container(
child: Center(
child: ListView(
shrinkWrap: true,
children: [
Text("Find users...",
textAlign: TextAlign.center,
),
],
),
),
);
}
buildSearchResults()
{
return FutureBuilder(
future: searchResults,
builder: (context, snapshot){
if(!snapshot.hasData)
return CircularProgressIndicator();
List<UserSearch> searchResults = [];
snapshot.data.forEach((docu){
AppUser user = AppUser.fromDocument(docu);
UserResult searchResult = UserResult(user);
searchResults.add(UserResult(user)); //This part is giving me the error
});
return ListView(
children: searchResults,
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: buildSearchField(),
body:
searchResults == null ? searchContainer(): buildSearchResults(),
);
}
}
class UserResult extends StatelessWidget {
final AppUser user;
UserResult(this.user);
#override
Widget build(BuildContext context) {
return Container(
child: Column(
children: [
GestureDetector(
onTap: showUserProfile(context,profileID: user.userId),
child: ListTile(
leading: CircleAvatar(
backgroundColor: Colors.yellow,
backgroundImage: Image.network(user.photoURL).image,
),
title: Text(user.firstName + " " + user.lastName),
),
),
Divider(
height: 2.0,
color: Colors.white54,
),
],
),
);
}
}
It is a different types. You need to change List type to UserList:
List<UserResult> searchResults = [];

Getting ExpansionPanelList to work inside Streambuilder in flutter

I'm trying to arrange some data streamed from Firebase with an ExpansionPanellist. The panelList is placed inside a StreamBuilder, and above the StreamBuilder i have a SingleChildScrollView.
I am able to get the list showing with the headers, but i can't get the expand/collapse function to work, so I am not able to see the body-text.
screenshot of the list
The expanding/collapinsg function worked outside the Streambuilder, but I was not able to access the data from Firebase then.
Any help will be much appreciated! If this is the wrong way of doing this, I will also be grateful for any pointers to alternative ways of achieving this. (There won't be any data added to the server while looking at past climbs and graphs, so a streambuilder might not be necessary if there are easier/better ways).
-Kristian
class Graphs extends StatefulWidget {
static String id = 'graphs_screen';
#override
_GraphsState createState() => _GraphsState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(tabs: [
Tab(text: 'Graphs'),
Tab(text: 'Stats'),
Tab(text: 'Climbs'),
]),
),
body: TabBarView(
children: [
//Image.asset('assets/images/line_graph.png'),
Expanded(child: NumericComboLinePointChart.withSampleData()),
Container(
child: Text(''),
),
SingleChildScrollView(
child: DataStream(),
),
],
)),
),
);
}
}
class DataStream extends StatefulWidget {
#override
_DataStreamState createState() => _DataStreamState();
}
class _DataStreamState extends State<DataStream> {
#override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _firestore
.collection('climbs')
.orderBy('Date', descending: true)
.snapshots(),
builder: (context, snapshot) {
List<ExpansionItem> expansionList = <ExpansionItem>[];
if (snapshot.hasData) {
final alldata = snapshot.data.docs;
for (var data in alldata) {
final dataFunction = data.data();
final grades = dataFunction['gradeScore'];
final climbDate = dataFunction['Date'];
final climbDateT = DateTime.fromMicrosecondsSinceEpoch(
climbDate.microsecondsSinceEpoch);
String climbDateString =
"${climbDateT.year.toString()}-${climbDateT.month.toString().padLeft(2, '0')}-${climbDateT.day.toString().padLeft(2, '0')} ${climbDateT.hour.toString()}-${climbDateT.minute.toString()}";
final climber = dataFunction['sender'];
final currentUSer = loggedInUser.email;
if (climber == loggedInUser.email) {
expansionList.add(ExpansionItem(
dateTimeHeader: climbDateString,
climbs: grades.toString()));
}
}
}
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
print('tap registered');
expansionList[index].isExpanded = !isExpanded;
});
},
children: expansionList.map((ExpansionItem item) {
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded) {
return Container(
child: Text(item.dateTimeHeader),
);
},
body: Container(
child: Text(item.climbs),
),
isExpanded: item.isExpanded,
);
}).toList(),
);
});
}
}
class ExpansionItem {
ExpansionItem({this.isExpanded: false, this.dateTimeHeader, this.climbs});
bool isExpanded;
final String dateTimeHeader;
final String climbs;
}
I also ran into this issue and managed to develop a "work-around" (sorry in advance, it's a bit messy).
The reason your expansion tiles are not expanding is due to the nature of expansionCallback function. Once you press the expand button it also causes your StreamBuilder to rebuild. Therefore, since you're initializing "expansionList" within the StreamBuilder it will reset "isExpanded" back to false no matter how many times you press it. So your best option is to initialize the expansionList outside of the StreamBuilder and modify it from within. Check below for my solution but I welcome anyone to optimize it and/or share a better one.
class ExpansionItem {
String headerValue;
bool isExpanded;
SplitObject item;
ExpansionItem({this.item, this.headerValue, this.isExpanded = false});
}
class MyExample extends StatefulWidget{
#override
_MyExampleState createState() => _MyExampleState();
}
class _MyExampleState extends State<MyExample> {
//Pick a number as large as you see fit to always be more than necessary.
List<ExpansionItem> expansionItems = List<ExpansionItem>.generate('anyNumber', (int index)=> ExpansionItem(isExpanded: false,));
#override
Widget build(BuildContext context) {
return GestureDetector(
child: Scaffold(
appBar: AppBar(
title: Text('Split',style: Theme.of(context).textTheme.headline3,),
),
body: SingleChildScrollView(
padding: const EdgeInsets.all(8),
child: Container(
child: StreamBuilder(
builder: (context, streamData){
if(streamData.hasData){
List<SplitObject> items = streamData.data;
//Save data to Expansion list by iterating through it.
for (var i = 0; i < items.length; i++){
try {
expansionItems[i].item =items[i];
expansionItems[i].headerValue =items[i].itemName;
} catch (e) {
// Catch any range errors after trimming list.
if(e.toString().contains('RangeError')) {
expansionItems.add(ExpansionItem(
item: items[i], headerValue: items[i].itemName));
}
}
}
// Trim list
expansionItems = expansionItems.getRange(0, items.length).toList();
return _buildListPanel(expansionItems);
} else {
return ListTile(
title: Text('No items to split.'),
);
}
},
stream: DatabaseService().splitItemData,
),
),
),
)
);
}
Widget _buildListPanel(List<ExpansionItem> expansionItems){
// print(expansionItems[0].isExpanded);
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded){
setState(() {
expansionItems[index].isExpanded = !isExpanded;
// print(expansionItems[index].isExpanded);
});
},
children: expansionItems.map<ExpansionPanel>((ExpansionItem item){
return ExpansionPanel(
headerBuilder: (BuildContext context, bool isExpanded){
print(item.isExpanded);
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(),
);
},
body: Container(),
isExpanded: item.isExpanded,
);
}).toList(),
);
}
}
You should create a class where your Expansion List will be, then your Stream builder must call it. Doing it this way Expansion Panel List callback will function just normal.
Look:
class _ExpansionPanelClass extends State<ExpansionPanelClass> {
#override
Widget build(BuildContext context) {
return ExpansionPanelList(
elevation: 3,
expansionCallback: (index, isExpanded) {
setState(() {
widget.product[index]['isExpanded'] = !isExpanded;
});
},
animationDuration: const Duration(milliseconds: 600),
children: widget.product
.map(
(item) => ExpansionPanel(
canTapOnHeader: true,
backgroundColor:
item['isExpanded'] == true ? Colors.cyan[100] : Colors.white,
headerBuilder: (_, isExpanded) => Container(
padding:
const EdgeInsets.symmetric(vertical: 15, horizontal: 30),
child: Text(
item['title'],
style: const TextStyle(fontSize: 20),
)),
body: Container(
padding:
const EdgeInsets.symmetric(vertical: 15, horizontal: 30),
child: Text(item['description']),
),
isExpanded: item['isExpanded'],
),
)
.toList(),
);
}
}
Then from your StreamBuilder:
StreamBuilder<QuerySnapshot>(
stream: dbProducts
.collection(ids[i])
.orderBy('order', descending: false)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
List<Map<String, dynamic>> _items = [];
for (var document in snapshot.data!.docs) {
Map data = Map.from(document.data() as Map);
if (data['hide'] == false) {
Map<String, dynamic> map = {
'id': _items.length,
'title': data['name'],
'description': data['ingredients'],
'isExpanded': false
};
_items.add(map);
}
}
return ExpansionPanelClass(product: _items);
} else {
return const Center(
child: CircularProgressIndicator(
color: Colors.brown,
),
);
}
},
),
That's all.

Firebase Query not working with Flutter, How to solve this?

I am trying to add a search functionality to my Flutter App, Everything works fine in the code, no errors are shown but when I search for username on my app screen no results are showing but sometime it throws an error saying "failed assertion: line 269 pos 10: 'data != null' The relevant error-causing widget was FutureBuilder" Especially when I use capital letter and has an empty space in the text.
I have attached the code for search.dart and user.dart file. Please help me out, I'm stuck here.
search.dart File
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:social_share/models/user.dart';
import 'package:social_share/pages/home.dart';
import 'package:social_share/widgets/progress.dart';
class Search extends StatefulWidget {
#override
_SearchState createState() => _SearchState();
}
class _SearchState extends State<Search> {
TextEditingController searchController = TextEditingController();
Future<QuerySnapshot> searchResultsFuture;
handleSearch(String query) {
Future<QuerySnapshot> users = usersRef
.where("displayName", isGreaterThanOrEqualTo: query)
.getDocuments();
setState(() {
searchResultsFuture = users;
});
}
clearSearch() {
searchController.clear();
}
AppBar buildSearchField() {
return AppBar(
backgroundColor: Colors.white,
title: TextFormField(
controller: searchController,
decoration: InputDecoration(
hintText: "Search for a user...",
filled: true,
prefixIcon: Icon(
Icons.account_box,
size: 28.0,
),
suffixIcon: IconButton(
icon: Icon(Icons.clear),
onPressed: clearSearch,
),
),
onFieldSubmitted: handleSearch,
),
);
}
Container buildNoContent() {
final Orientation orientation = MediaQuery.of(context).orientation;
return Container(
child: Center(
child: ListView(
shrinkWrap: true,
children: <Widget>[
SvgPicture.asset(
'assets/images/search.svg',
height: orientation == Orientation.portrait ? 300.0 : 200.0,
),
Text(
"Find Users",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.w600,
fontSize: 60.0,
),
),
],
),
),
);
}
buildSearchResults() {
return FutureBuilder(
future: searchResultsFuture,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return circularProgress();
}
List<Text> searchResults = [];
snapshot.data.documents.forEach((doc) {
User user = User.fromDocument(doc);
searchResults.add(Text(user.username , style: TextStyle(color: Colors.black, fontSize: 20.0),));
});
return ListView(
children: searchResults,
);
},
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Theme.of(context).primaryColor.withOpacity(0.8),
appBar: buildSearchField(),
body:
searchResultsFuture == null ? buildNoContent() : buildSearchResults(),
);
}
}
class UserResult extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Text("User Result");
}
}
user.dart File
import 'package:cloud_firestore/cloud_firestore.dart';
class User {
final String id;
final String username;
final String email;
final String photoUrl;
final String displayName;
final String bio;
//Constructor
User({
this.id,
this.username,
this.email,
this.photoUrl,
this.displayName,
this.bio,
});
factory User.fromDocument(DocumentSnapshot doc){
return User(
id: doc['id'],
email: doc['email'],
username: doc['username'],
photoUrl: doc['photoUrl'],
displayName: doc['displayName'],
bio: doc['bio'],
);
}
}
Firebase Database Data ScreenShots
Firebase Users Data Screenshot
if looks like if the actual data is null you would get an error.
try:
if(!snapshot.hasData || snapshot.data?.documents == null)
instead of:
if (!snapshot.hasData)
reference - https://github.com/flutter/flutter/issues/22199
Solved
After I changed the if statement to the following line it's working.
if(!snapshot.hasData || snapshot.data.documents == null)

Saving dialog content before closing it

I'm making a dialog containing a list of items, each of which includes an editable text field.
I'd like to save the contents of edited text fields to a SQLite database on dialog close.
How would I do that? There seems to be no such thing as an onClose listener in Flutter and once the dialog is closed, I won't be able to retrieve the text from text fields.
As You have not shared any code - so i share a minimal example of what you intend to do.
Data can be passed with the use of Navigator.
class DemoApp extends StatefulWidget {
#override
DemoAppState createState() {
return new DemoAppState();
}
}
class DemoAppState extends State<DemoApp> {
String val = 'Empty';
TextEditingController cntrl = TextEditingController();
#override
void dispose() {
cntrl.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Value is -- $val'),
RaisedButton(
onPressed: () async {
val = await showDialog(
context: context,
builder: (context) {
cntrl.clear();
return AlertDialog(
title: Text('Enter Value'),
content: TextField(
controller: cntrl,
),
actions: <Widget>[
FlatButton(
onPressed: () {
Navigator.pop(context, cntrl.text);
},
child: Text('Save')),
],
);
});
setState(() {});
},
child: Text('Edit Value'),
)
],
),
)));
}
}

Resources