streambuilder not displaying data in list - flutter

I'm trying to display a list of employees in my app. Here's the code I got so far:
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 20,top: 20),
child: Container(
height: 40,
width: 120,
decoration: BoxDecoration(
color: Colors.grey.withOpacity(0.12),
borderRadius: BorderRadius.circular(8)),
child: Padding(
padding: const EdgeInsets.all(10),
child: Text("Employees",
style: TextStyle(
fontSize: 22,
color: Colors.black,
fontWeight: FontWeight.w600,
)),
),
),
),
StreamBuilder(
stream: Firestore.instance.collection("Employees").snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: Text("Fetching data..."));
} else if(snapshot.connectionState == ConnectionState.done){
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(snapshot.data.documents[index]['name']));
},
);
} else {
return Text("hol up");
}
}),
],
);
When I run the app, it just shows 'Employees' and 'hol up' in a column. Why does the list of employees not show?

I solved the issue by simply adding shrinkWrap: true in my listview.

This should work. Also get the data from the indexed document.
ListTile(
title: Text(snapshot.data.documents[index].data['name']));

Related

flutter combine two stream where the second depends on the first?

i have two collection,
users collection
like collection.
in my like i have the list of like with there id, i am now using stream to fetch the list like user but. so if the user change his profile image it cant be updated in the like collection, so what i did is after fetching the list, i pass the id to another stream to get upadate from Users collection. this alot of bioler plate code. i am looking for way to combine this stream together.
here is a sample code
StreamBuilder(
stream: firestore
.collection('Matches')
.doc(auth.currentUser.uid)
.collection('Match')
.orderBy('chatTimeStamp').snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Container();
}
if (snapshot.connectionState ==
ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.data.docs.isEmpty) {
return Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RippleAnimation(
repeat: true,
color: Colors.white,
minRadius: 100,
ripplesCount: 6,
child: Material(
elevation: 8.0,
shape: CircleBorder(),
child: CircleAvatar(
backgroundColor: themedata.darkTheme
? Colors.black
: Colors.white,
child: Image.asset(
'assets/1.png',
),
radius: 80.0,
),
),
),
Flexible(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'No Message Yet!',
textAlign: TextAlign.center,
style: GoogleFonts.raleway(
textStyle: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20,
),
),
),
),
),
],
),
);
}
return ListView.separated(
separatorBuilder: (_, index) => Padding(
padding:
EdgeInsets.only(left: 120.0, right: 40),
child: Divider(
color: Colors.white,
thickness: 1.0,
),
),
shrinkWrap: true,
itemCount: snapshot.data.docs.length,
itemBuilder: (context, index) {
final data =
snapshot.data.docs[index].data()['Match'];
//here is where it depend on the value
return StreamBuilder(
stream: firestore
.collection('users')
.doc(data['id'])
.snapshots(),
builder: (context, snapshotid) {
final active = snapshotid.data.data();
if (snapshotid.hasError) {
return Container();
}
if (snapshotid.connectionState ==
ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator());
}
if (snapshotid.connectionState ==
ConnectionState.none) {
return Container();
}
if (!snapshotid.hasData) {
return Container();
}
For combining two streams you can use combine2 method from rxdart library. this library has all of the stream class features + some extra functionality which is really useful. for more detail you can see the official documentation here.
note: for using this library methods and functionalities you should also define streams by this library classes.
for example:
Stream stream, may be PublishSubject stream.

flutter- data is not refreshing in stream builder when a condition update in firestore query

I am facing problem in using stream builder. Actually, I have a dropdown list and below it I have gridview to show product categories according to options chose in dropdown list. I have to use two stream builders, one for option(s) list in dropdown and other is for gridview. Dropdown is wroking fine but gridview is not changing data according to option choose in dropdown list.
Please help
My dropdown widget
Widget dropDownMenu({
required Size size,
BuildContext? context,}) {
return StatefulBuilder(builder: (context, setState) {
return FutureBuilder(
future: FirebaseFirestore.instance
.collection('options').get(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Error while loading'));
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: SpinKitFadingCircle(
itemBuilder: (BuildContext context, int index) {
return DecoratedBox(
decoration: BoxDecoration(
color: index.isEven
? MyStyles.themeData().primaryColor
: Colors.green,
),
);
},
),
);
}
if (snapshot.hasData && snapshot.data!.docs.isEmpty) {
return Center(child: Text('No Data'));
}
return Container(
height: size.height * 0.100,
padding: EdgeInsets.all(20.0),
color: Colors.white,
child: DropdownButton<String>(
dropdownColor: Colors.white,
elevation: 1,
value: viewModel.dropDownValue!,
hint: Text('Choose one option'),
items:
snapshot.data!.docs.map<DropdownMenuItem<String>>((value) {
return DropdownMenuItem<String>(
value: value.get('options'),
child: Text(
value.get('options'),
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
style: GoogleFonts.poppins(
color: MyStyles.themeData().primaryColor,
fontSize: size.height * 0.024,
fontWeight: FontWeight.w600,
),
),
);
}).toList(),
onChanged: (value) {
setState(() {
viewModel.dropDownValue = value;
});
}),
);
},
);
});}
My gridview Widget
Widget buildGridView({Size? size, BuildContext? context}) {
return Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('categories')
.where('options', isEqualTo: viewModel.dropDownValue)
.snapshots(),
builder:
(BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Center(child: Text('Error while loading'));
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: SpinKitFadingCircle(
itemBuilder: (BuildContext context, int index) {
return DecoratedBox(
decoration: BoxDecoration(
color: index.isEven
? MyStyles.themeData().primaryColor
: Colors.green,
),
);
},
),
);
}
if (snapshot.hasData && snapshot.data!.docs.isEmpty) {
return Center(child: Text('No Categories available'));
}
return GridView.builder(
padding: const EdgeInsets.only(bottom: 70),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200,
childAspectRatio: 1,
crossAxisSpacing: 20,
mainAxisSpacing: 20,
),
itemCount: snapshot.data!.size,
itemBuilder: (BuildContext ctx, index) {
return GestureDetector(
onTap: () {},
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 3.0),
height: size!.height * 0.200,
width: double.infinity,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Color(0x99C4C4C4),
blurRadius: 12,
offset: Offset(4, 4),
spreadRadius: 0,
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: size.height * 0.120,
width: size.width * 0.120,
child: Image.network(
snapshot.data!.docs[index]['image'])),
SizedBox(height: size.height * 0.015),
Text(
snapshot.data!.docs[index]['name']!,
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: GoogleFonts.poppins(
color: MyStyles.themeMode().textColor,
fontSize: size.height * 0.022,
fontWeight: FontWeight.w500,
),
),
],
),
),
);
},
);
},
),
),
);}
I want to rebuild stream everytime I change options in dropdown. How can I achieve this?

How to make flutter display lot of data from json

I got a page in flutter than contains future builder, and the result of it displayed in list view builder. When I get small amount of data, flutter display the data without any problem. But when I get large amount of data, it display nothing.
What I get from this problem is when I get large amount of data, future builder hasn't finished get the data before the page is shown.
How can I make the page wait for the future finished to get the data before the page is shown?
Thanks
FutureBuilder<List<SalesTable>>(
future: SelectSalesTable.getSalesTable(widget.kodesales,
daterange1.format(widget.tgl1), daterange2.format(widget.tgl2)),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.none) {
return new Text('No Data..!!');
} else if (snapshot.connectionState == ConnectionState.waiting) {
return new Center(child: CircularProgressIndicator());
} else {
if (snapshot.hasData) {
List<SalesTable> data = snapshot.data;
return Container(
child: Column(
children: [
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(5, 5, 5, 5),
child: Card(
shadowColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 10,
child: Padding(
padding:
const EdgeInsets.fromLTRB(5, 10, 5, 10),
child: ListTile(
title: Text(
data[index].name +
' | ' +
data[index].Category,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold)),
subtitle: Column(
children: <Widget>[
Row(
children: <Widget>[
Expanded(
child: Text(
'Date : ' +
dateformat3.format(
data[index]
.date1),
style: TextStyle(
fontWeight:
FontWeight.bold)),
)
],
),
],
),
onTap: () {},
),
),
),
),
],
);
},
itemCount: data.length,
),
],
));
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
}
return Center(child: CircularProgressIndicator());
},
)

flutter scrollView not scrolling in Stream

I am working on a Flutter project that uses Firebase and has a StreamBuilder that creates a card that is similar to a blog App. Whenever I add a lot of "blogs", I get a bottom Overflow error and when I wrap body: MemoirsList(), in a SingleChildScrollView, the app won't let me scroll down.
Here is the code for the MemoirsList():
Widget MemoirsList() {
return Container(
child: memoirsStream != null
? ListView(
shrinkWrap: true,
children: <Widget>[
StreamBuilder(
stream: memoirsStream,
builder: (context, snapshot) {
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
itemBuilder: (context, index) {
return MemoirsCard(
authorName: snapshot.data.documents[index].data['authorName'],
title: snapshot.data.documents[index].data["title"],
description: snapshot.data.documents[index].data['description'],
imgUrl: snapshot.data.documents[index].data['imgURL'],
);
});
},
)
],
)
: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
}
Code for MemoirsCard():
class MemoirsCard extends StatelessWidget {
String imgUrl, title, description, authorName;
MemoirsCard({#required this.imgUrl, #required this.title, #required this.description, #required this.authorName});
#override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.only(bottom: 20),
height: 200,
child: Stack(
children: <Widget>[
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Image.network(
imgUrl,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover
)
),
Container(
height: 200,
decoration: BoxDecoration(
color: Colors.black54.withOpacity(0.3),
borderRadius: BorderRadius.circular(10),
),
),
Container(
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
title,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 32,
fontWeight: FontWeight.w700
),
),
SizedBox(height: 8),
Text(
description,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 15,
fontWeight: FontWeight.w400
)
),
],
),
),
],
)
);
}
}
Listview.Builder inside Listview, it's not a good option which the flutter suggest you
Just replace top Listview with Column
Modify code like this
SingleChildScrollView(
child: Column(
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
...
Here is the final code for anyone who is wondering:
Widget MemoirsList() {
return SingleChildScrollView(
child: memoirsStream != null
? Column(
children: <Widget>[
StreamBuilder(
stream: memoirsStream,
builder: (context, snapshot) {
if(snapshot.data == null) return CircularProgressIndicator(); //Removes called documents on null error
return ListView.builder(
padding: EdgeInsets.symmetric(horizontal: 16),
itemCount: snapshot.data.documents.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return MemoirsCard(
authorName: snapshot.data.documents[index].data['authorName'],
title: snapshot.data.documents[index].data["title"],
description: snapshot.data.documents[index].data['description'],
imgUrl: snapshot.data.documents[index].data['imgURL'],
);
});
},
)
],
)
: Container(
alignment: Alignment.center,
child: CircularProgressIndicator(),
),
);
}

Insert data from futureBuilder into table

I want to display the data obtained from futureBuilder into the table, this is the code that I tried but when I run browse an error appears like this
FutureBuilder(
future: UserController.getActivity(_selectedUser),
builder: (context, snapshot) {
if (snapshot.hasData != null) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, position){
var item = snapshot.data.elementAt(position);
return Container(
child: Table(
children: List<TableRow>.generate(10, (i) {
return TableRow(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 0.5, color: Colors.grey))),
children: [
Container(
padding: EdgeInsets.all(18),
child: Text(
//data[i].author.toString(),
"${item["activity"]["project"]}",
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
),
),
Container(
padding: EdgeInsets.all(18),
child: Text(
//data[i].stars.toString(),
item["created_at"],
style: TextStyle(
fontSize: 14,
color: Colors.black,
),
),
)
]);
})),
);
}
);
}
},
),
if I use listView in displaying data, it becomes ineffective because the data is a lot
Error is here at this line
itemCount: snapshot.data.length,
length is not found in the snapshot. You need to check the return type of future UserController what it's returning.
For being to verify your code that it's working fine you can set the default value
Just to verify that UI working fine
itemCount: 10
after that you need to check your return type.