Reputation: 35
I'm trying to display an message, but unfortunately I think I'll need to change my method.
So I've resumed some code
child: FutureBuilder<List<Product>>(
future: products,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
final products = snapshot.data!;
return Padding(
padding: const EdgeInsets.all(10.0),
child: ListView.builder(
itemCount: products.length, // currently has 400 items
itemBuilder: (context, index) {
if (difference == 0) {
return cardUI(
...
);
} else {
return Text('Nothing to display!');
}
}));
})),
How can I manage to return the message only one time? Do I need to change all the code? Since it's displaying almost 250 times 'Nothing to display'
Edit: This is what I'm using to calculate the difference!
DateTime productExpire = DateTime.parse(products[index].date);
final productDate = productExpire;
final today = DateTime.now();
final difference = calcDays(
today, productDate);
Upvotes: 0
Views: 77
Reputation: 629
The solution that comes to mind is to make products only equal to the products that have a difference of days from today of zero, so then based on products.length
you can either return a Text()
(if products.length == 0
) or call ListView.builder
(if products.length > 0
).
Basically:
Instead of this:
All products
products = [thisProdHasDifferenceOfZero, thisOneDoesnt, thisOneDoes, thisOneDoesnt, ...]
(products.length == 400 every time)
You can just have:
Only products that you want to work with
products = [thisProdHasDiffOfZero, thisOneToo, thisOneToo, ...]
(products.length <= 400)
In your code:
Instead of calculating the difference your way, use this:
This method calculates the difference between two dates, the one you're using may run into some bugs... check this answer for more information
int daysBetween(DateTime from, DateTime to) {
from = DateTime(from.year, from.month, from.day);
to = DateTime(to.year, to.month, to.day);
return (to.difference(from).inHours / 24).round();
}
Then:
child: FutureBuilder<List<Product>>(
future: products,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
final today = DateTime.now();
final products = (snapshot.data! as List<Product>).where((product) => daysBetween(product.date, today) == 0).toList;
// Now you know that every product inside 'products', if there's any, has a day difference of 0.
return Padding(
padding: const EdgeInsets.all(10.0),
// 'products' can be empty since you may have 0 products that have the difference you are looking for.
// In that case you return the text.
child: (products.length == 0) ?
return Text('Nothing to display!');
: return ListView.builder( // If products has one or more items...
itemCount: products.length,
itemBuilder: (context, index) {
return cardUI(
...
);
}
)
...
Upvotes: 1
Reputation: 63569
After getting all products filter them and create another list of product that will satisfy difference==0.
final products = snapshot.data!;
List<Product> temp = [];
// temp = products.where((p) => validation(p) == 0).toList();
for(final p in products)
{
int difference = yourValidation(p);
if(difference == 0) temp.add(p);
}
//...
child: ListView.builder(
itemCount: temp.length,
More about List
Upvotes: 0
Reputation: 352
You want to show a single error if the listview.builder does not have any data right? Hope I am not getting you wrong. If so you can use the ternary operator where you have mentioned the listview.builder to make it conditional.
or you can try to update the item count with condition.
itemcount: difference ==0? products.length : 1,
Upvotes: 0