I try to using searchdelgit with future list from JSON, when. But I got
this error:
formatException :Unexpected character (at line 2 , character1)
altho I already use the same code without search page and it works perfectly
any idea guys
#override
Widget buildResults(BuildContext context) {
// show some result based on the selection
if (query.length < 3) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Text(
"Search term must be longer than two letters.",
),
)
],
);
}
return FutureBuilder(
future: _fetchProductSearch(query),
builder: (context, AsyncSnapshot<List<Products>> snapshot) {
if (!snapshot.hasData) {
return Text(snapshot.error.toString());
} else if (snapshot.data.length == 0) {
return Column(
children: <Widget>[
Text(
"No Results Found.",
),
],
);
} else {
var results = snapshot.data;
return ListView.builder(
itemCount: results.length,
itemBuilder: (context, index) {
var result = results[index];
return ListTile(
title: Text(result.artitle),
);
},
);
}
},
);
}
formatException :Unexpected character (at line 2 , character1)
Related
One of my routes shows current data which is stored in firestore database. I am calling the function to retrieve the data from firestore in the initState method. The page will show all the data which are retrieved from firestore. It works fine i.e, when the user navigates to this page (quotesPage) it shows the data. But while navigating, for some fraction of seconds it shows error that the local variable which stores the retrieved data is null. It happens for only that fraction of seconds after which it receives the data and shows the data. So when the user navigates to that page, I want to show a progress indicator untill it receive the data. here is my code,
Map<String, dynamic> userInfo = {};
Future<void> getQoutes() async {
var data = await FirebaseFirestore.instance.collection('user').doc(auth.currentUser!.uid).get();
setState(() {
userInfo = data.data() as Map<String, dynamic>;
});
}
#override
void initState() {
getQoutes();
super.initState();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Some Quotes',
),
backgroundColor: Colors.deepOrange,
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card_fun(userInfo['quotes'][index]);
}
)
)
],
),
)
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await popUpForm();
},
),
);
I am calling the function getQuotes() from initState() which will store the data to Map variable userInfo. So how to show a progress indicator untill the variable 'userInfo' gets data ?
Can anyone help ?
This is the updated code
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Some Quotes',
),
backgroundColor: Colors.deepOrange,
),
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FutureBuilder<void>(
future: getQoutes(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
if(snapshot.hasError) {
return Text('Error : ${snapshot.error}');
}
return Expanded(
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card_fun(userInfo['quotes'][index]);
}
)
);
default:
return const CircularProgressIndicator();
}
},
)
],
),
)
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await popUpForm();
},
),
);
You should try with Future builder or stream builder and here is the example with Future builder
FutureBuilder<String>(
future: getQoutes(), // async work
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting: return CircularProgressIndicator();
default:
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
else
return Expanded(
child: ListView.builder(
itemCount: 3,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card_fun(userInfo['quotes'][index]);
}
)
);
}
},
)
For more read this article
another approach that might be worth looking at is using a addPostFrameCallback method called from your initState in which you can await the necessary condition and take appropriate action and trigger a setState.
I don't know whether this is a dumb question or not. Pardon me if it is.
I created a streamBuilder and now I want to extract it's AsyncSnapshot and save as a global variable. Currently I only have access to that snapshot is, inside the streamBuilder widget. But I want that snapshot data to update some widgets outside that streamBuilder widget. I have added a comment to below code:
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: _crudStorage.all(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.active:
case ConnectionState.waiting:
if (snapshot.data == null) {
return const Center(
child: CircularProgressIndicator(),
);
}
final tasksList = snapshot.data as List<Task>; //I want to extract this
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
tasksList.isEmpty
? const RiveBird()
: Expanded(
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: tasksList.length + 1,
itemBuilder: (context, index) {
if (index == tasksList.length) {
return const SizedBox(
height: 85.0,
width: double.infinity,
);
}
final task = tasksList[index];
return Dismissible();
},
),
),
],
);
default:
return const Center(
child: CircularProgressIndicator(),
);
}
},
),
);
}
here is the code
isClicked? StreamBuilder<QuerySnapshot>(
stream: db.where("Uid", isEqualTo: Uid.text).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return SingleChildScrollView(
child: ListView(
children: snapshot.data!.docs.map((doc) {
return ListView(
children: [
Text(doc.data()['name']),
Text(doc.data()['DateOfBirth']),
Text(doc.data()['crime']),
Text(doc.data()['criminalHistory']),
],
);
}).toList(),
),
);
}
},
)
:Container()
]));
}
i have tried to replace list view with column ,and inner list view with card but still same error
Add shrinkWrap: true to both your ListView widgets
isClicked? StreamBuilder<QuerySnapshot>(
stream: db.where("Uid", isEqualTo: Uid.text).snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
} else {
return SingleChildScrollView(
child: ListView(
shrinkWrap: true,
children: snapshot.data!.docs.map((doc) {
return ListView(
shrinkWrap: true,
children: [
Text(doc.data()['name']),
Text(doc.data()['DateOfBirth']),
Text(doc.data()['crime']),
Text(doc.data()['criminalHistory']),
],
);
}).toList(),
),
);
}
},
)
:Container()
]));
I'm trying to create a Futurebuilder function to call and display all data that inserted in database unfortunately I got this error 'UnimplementedError' and im pretty stock on this any suggestion will be appreciated.
Here in my full code for implementation to display data in been trying to fix my error 'UnimplementedError' in which I'm trying to do is to display inserted in list view not in web view any suggestion will be appreciated.
body: Center(
child: Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FutureBuilder<ContactsDao>(
future: _calltheStream(),
builder: (BuildContext context,
AsyncSnapshot<ContactsDao> snapshot) {
if (!snapshot.hasData ||
snapshot.connectionState == ConnectionState.none) {
return Container(
child: CircularProgressIndicator(),
);
} else {
return StreamBuilder<List<ContactObject>>(
stream: snapshot.data.findallContactsById(),
builder: (context, snapshot) {
if (!snapshot.hasData ||
snapshot.connectionState ==
ConnectionState.none) {
return Container(
child: CircularProgressIndicator(),
);
} else {
if(widget.Contactlist.length != snapshot.data.length){
widget.Contactlist = snapshot.data;
}
if(snapshot.data.length == 0){
return Center(
child: Text('No Data Found'),
);
}
return Expanded(
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data.length,
itemBuilder:
(BuildContext context, int index) {
return Card(
child: ListTile(
leading: Checkbox(
value: widget.Contactlist[index].isSelect,
onChanged: (bool value) {
setState(() {
widget.Contactlist[index].isSelect = value;
});
},
),
trailing: GestureDetector(
onTap: () {
_selectedDetele(snapshot.data[index].id);
},
child: Icon(Icons.delete),
),
title: Text('${snapshot.data[index].task}',maxLines: 1,),
subtitle: Text('${snapshot.data[index].time}',style: TextStyle(fontSize: 10),),
));
}),
);
}
}); //DATA
} //DATA
}), // DATA
], // DATA
), // DATA
),//DATA
),
Future<ContactsDao> _calltheStream() async { //GET ALL DATA HERE
ContactDatabase contactDatabase = await widget.database;
widget._contactsdao = contactDatabase.contactsDao;
return contactDatabase.contactsDao;
}
I have a simple problem in flutter but I cant quite figure out how to solve it. So here it is. I'm trying to show a message in my app if the snapshot that I'm calling has no data in my firebase database.
I have this code:
return Scaffold(
body: Container (
child: new LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.020,
),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
child: Column(
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: db.collection('CONFIRMED HELP BENEFICIARY').where('Respondents_ID', isEqualTo: '${widget.UidUser}').snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList());
}
else {
return Container(
color: Colors.red,
height: 200,
width: 200,
child: Text("No Data"));
)
],
);
},
),
),
);
Inside my singlescrollview, I have a streambuilder in it. Also an if else. So if the"snapshot.hasdata" I'm showing a list of data and it successfully shows that. But the problem is in the "else". I've been trying to show a container that has a color:red and a text that contains "No Data" but I quite cant figure out how to ## It shows the container for milliseconds then it disappear ##. Please help.
if(!snapshot.hasData){
// still waiting for data to come
return circularProgress();
}
else if(snapshot.hasData && snapshot.data.isEmpty) {
// got data from snapshot but it is empty
return Text("no data");
}
else {
// got data and it is not empty
return ListView(
children: snapshot.data,
);
}
},
This works for me on Flutter 2.10.3 with null safety.
if (!snapshot.hasData) {
// waiting for data
return CircularProgressIndicator();
} else if (snapshot.data?.size == 0) {
// collection has no data
return _noDataWidget();
} else {
return ...;
}
There was a few brackets missing. That caused the problem. I fixed the code for you.
return Scaffold(
body: Container(
child: new LayoutBuilder(
builder: (BuildContext context, BoxConstraints viewportConstraints) {
return Column(
children: <Widget>[
SizedBox(
height: MediaQuery.of(context).size.height * 0.020,
),
SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Container(
child: Column(
children: <Widget>[
StreamBuilder<QuerySnapshot>(
stream: db.collection('CONFIRMED HELP BENEFICIARY')
.where('Respondents_ID', isEqualTo: '${widget.UidUser}')
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Column(
children: snapshot.data.documents
.map((doc) => buildItem(doc))
.toList());
}
else {
return Container(
color: Colors.red,
height: 200,
width: 200,
child: Text("No Data"));
}
}
)
],
),
),
),
],
);
},
),
),
);
if(!snapshot.hasData){
return circularProgress();
}
else if(snapshot.data.docs.isEmpty){
return Text("There is no data here");
//Or you can show any widget you want
}else{
return ListView()
}