Flutter ListView builder never completes - flutter

So im stuck on something that normally just works.
I have a firebase collection which contains a list of temmplates, i want to show these templates as a list view tile.
Stepping through the code reveals that the stream returns the items successfully , however when it reaches the itemCount property of the ListView it jumps out of the IF statement entirely and continues to display the loading indicator.
Debug console isnt showing any errors at all
StreamBuilder(
stream: firestoreDatabase.templatesStream(),
initialData: new List<AppTemplate>(),
builder: (context, snapshot) {
if (snapshot.data != null) {
List<AppTemplate> templates = snapshot.data;
ListView.builder(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return ListTile(
title: Text(templates[index].title),
subtitle: Text(
templates[index].description == null ||
templates[index].description == ""
? "N/A"
: templates[index].description),
leading: Icon(Icons.collections),
trailing: GestureDetector(
onTap: () => {},
child: Icon(Icons.delete),
),
);
},
itemCount: templates.length,
);
} else if (snapshot.hasError) {
return Center(child: Text('Error'));
}
return Center(
child: CircularProgressIndicator(),
);
},
),

Related

Flutter Visibility widget not working third time

I have wrapped ListView.builder inside Visible widget, and the button for its visible property is in a ListTile widget with variable _currencyVisible.
The widget Visible works 2 times i.e. false/hidden(default), then changes to visible when clicked, and again hides on the second click, but it doesn't work after that. Printing on console _currencyVisible shows correct data.
Here's my code:
menuItems(BuildContext context) {
bool _currencyVisible = false;
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListView(
children: [
ListTile(
title: FutureBuilder<dynamic>(
future: getUserCurrencySymbol(),
builder:(BuildContext context, AsyncSnapshot<dynamic> snapshot) {
return Text("Currency " + snapshot.data.toString());
}),
trailing: IconButton(
icon: Icon(Icons.refresh),
onPressed: () { setState(() { _currencyVisible = !_currencyVisible; }); },
),
),
Visibility(
visible: _currencyVisible,
child: ListView.builder(
shrinkWrap: true,
itemCount:
currency.allCurrenciesList.length,
itemBuilder: (context, index) {
for (Currency c in currency.allCurrenciesList) {
currency.allCurrenciesList.removeAt(0);
return Card(
child: ListTile(
title: Text(c.country),
subtitle: Text(c.shortCurrency),
trailing: Text(c.symbol),
onTap: () {
saveUserCurrency(c.country, context);
},
),
);
}
return Text("Not Null");
},
),
),
],
);
},
);
}
You are removing all of the data from your currency list. The widget is showing correctly, but there is no data to display.
Remove this line
currency.allCurrenciesList.removeAt(0);
Don't loop through the currencies in itemBuilder. Use index instead.
Visibility(
visible: _currencyVisible,
child: ListView.builder(
shrinkWrap: true,
itemCount: currency.allCurrenciesList.length,
itemBuilder: (context, index) {
final c = currency.allCurrenciesList[index];
return Card(
child: ListTile(
title: Text(.country),
subtitle: Text(c.shortCurrency),
trailing: Text(c.symbol),
onTap: () {
saveUserCurrency(c.country, context);
},
);
}
return Text("Not Null");
),
),

Flutter Qs : The getter 'length' was called on null

So I already make Condition where if the data called is null so it will Show No Data but it still have an Error.
Here's the code
Center(
child: ListView.builder(
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
if (data[index] == null) {
return Container(
child: Center(
child: Text(
"No News"
)
)
);
} else {
return GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
DetailNewsScreen(
data: data[index],
)));
},
child: Card(
child: Row(
but it still show error
You have to check if your data variable is null, otherwise you cannot call data.length as the itemCount
You're currently checking if data[index] is not null but not data itself
You could try :
Center(
child: ListView.builder(
itemCount: data == null ? 0 : data.length,
itemBuilder: (BuildContext context, int index) {
if (data[index] == null) {
return Container(child: Center(child: Text("No News")));
} else {
// return whatever widget you want
}
}),
),
the data is null, not data[someIndex]
itemCount: data.length,
You didnt cover the case where data==null. The most straightforward way of fixing it, is to assing empty array.
if(data==null) data=[]; somewhere prior building the view.

The getter 'documents' was called on null

I'm using flutter and firebase to make a to-do list. It keeps showing me this error even after I checked if my snap.data == null .But I am not sure why still doesn't work.
please help. I have checked similar problems like this but still didn't solve
sorry for my English
body: StreamBuilder(
stream: Firestore.instance.collection("MyTodos").snapshots(),
builder: (context, snapshots) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshots.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshots.data.documents[index];
return Dismissible(
key: Key(index.toString()),
child: Card(
child: ListTile(
title: Text(documentSnapshot["todoTitle"]),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
todos.removeAt(index);
});
},
),
),
),
);
},
);
},
)
StreamBuilder has a default state before it gets any data at all, and you need to check for this state so you don't try to build using data that doesn't exist yet. You can do this by checking either snapshots.hasData or snapshots.data == null:
StreamBuilder(
...
builder: (context, snapshots) {
if (!snapshots.hasData) {
return CircularProgressIndicator();
}
else {
return ListView.builder(
...
);
}
},
),

How to show loaded item in the list when rest of the items are being loaded in flutter future builder?

I am fetching a list of data and I would like to show the loaded items in the Future builder's list view while the rest of the items are being loaded, is it possible?
I have a ListView Builder inside a FutureBuilder, The Api call fetches 15 items and assigns to the list here FinalDataList
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
title: Text('All Artworks',textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.bold)),
centerTitle: true,
backgroundColor: Theme.of(context).primaryColor,
),
body: FutureBuilder(
future: dataFuture,
builder: (context,snapshot){
if(finalDataList.length > 0){
return RefreshIndicator(
onRefresh: (){
this._showToast(context);
return this.refreshHomePage();
},
child: ListView.builder(
scrollDirection: Axis.vertical,
itemCount: finalDataList!=null?finalDataList.length:0,
itemBuilder: (BuildContext context, int index){
return new Card(
child: Text(finalDataList[index]['title']),
);
},
),
);
}else{
return new Center(
child: new CircularProgressIndicator(
valueColor: new AlwaysStoppedAnimation<Color>(Theme.of(context).primaryColor),
),
);
}
}
),
);
What happens now is the entire widget of lists with 15 items only shows after all of them are loaded. How can I show the loaded items first while the remaining items are being loaded ?
You can have a list of futures and use ListView.builder to await on each one individually.
ListView.builder(
itemCount: futureList.length,
itemBuilder: (context, index) => FutureBuilder(
future: futureList[index],
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator(...);
} else {
return Center(...);
}
},
),
),
How you convert dataFuture into futureList will depend on how exactly you are creating dataFuture in the first place.

Flutter: When the snapshot is empty the widget disappears

I am trying to build a search list, the list is working fine but if the result is empty i need to show no data. I tried the following code but the widget holds for a second and then disappear
FutureBuilder(
future: getSearchedProducts(widget.searchString),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (!snapshot.hasData) {
return Center(
child: Container(
child: Text('No Data Found.'),
),
);
} else {
return ListView.builder(
shrinkWrap: true,
itemCount: searchResult.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Image.network(searchResult[index].proThumbnail),
title: Text(searchResult[index].proName),
onTap: () {
print(searchResult[index].proName);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ProductPage(prodid: searchResult[index].proId);
}));
},
),
);
});
}
})
Can anyone help me with this.
Thank you in advance.
I just write the code as below and it works.
FutureBuilder(
future: getSearchedProducts(widget.searchString),
builder: (BuildContext context, AsyncSnapshot snapshot) {
print('length of list ${searchResult.length}');
if (searchResult.length==0) {
return Center(
child: Text('No data'),
);
}
else if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(),
);
}
else {
return ListView.builder(
shrinkWrap: true,
itemCount: searchResult.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
return Card(
child: ListTile(
leading: Image.network(searchResult[index].proThumbnail),
title: Text(searchResult[index].proName),
onTap: () {
print(searchResult[index].proName);
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ProductPage(prodid: searchResult[index].proId);
}));
},
),
);
});
}
}),
In your Code in Else part before - return ListView.builder- add the following code.
...
else {
if (searchResult.length == 0)
{
return Center(child: const Text('No Date'));
}
return ListView.builder .....