I try to code my first app in flutter. It shows a list of items then once tapped, shows the details.
When moved back – list of items is shown again, from where I can delete an item by tapping trash icon. Once the icon is tapped AlerDialog comes up to confirm action.
Here I have an issue… how to display a text ‘No data to display’ on empty list after AlertDialog is closed.
I do not know why this text is not displayed? Can you please advice?
setState(() {
posts.removeAt(index);
if(posts.isEmpty)
{
const Text("No data to display"); // <---- WHY this text is NOT displayed
}
});
the entire code looks more or less like this:
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
appBar: AppBar(
backgroundColor: Colors.grey[900],
title: const Text('Some text'),
actions: [
IconButton(
onPressed: signUserOut,
icon: const Icon(Icons.logout),
)
],
),
body: Center(
child: FutureBuilder<List<Post>>(
future: postsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator(
backgroundColor: Colors.black,
valueColor: AlwaysStoppedAnimation<Color>(Colors.green)
);
} else if (snapshot.hasData) {
return buildPosts(snapshot.data!);
} else {
return const Text("No data to display");
}
},
),
),
);
}
Widget buildPosts(List<Post> posts) {
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
final List<ChartData> chartData = [
ChartData('', post.proc!.toDouble(), Colors.green),
ChartData(
'', (100.toDouble() - post.proc!.toDouble()), Colors.black),
];
return GestureDetector(
onTap: () {
loadListDetails(post.id!, post.lista!);
},
child: Container(
color: Colors.white,
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 0),
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 15),
height: 150,
width: double.maxFinite,
child: Row(
children: [
Expanded(...),
Expanded(
flex: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 2,
child: Row(
children: [
const Text(
' ', textAlign: TextAlign.right,
style: TextStyle(
fontWeight: FontWeight.normal,
fontSize: 14,
color: Colors.black)),
IconButton(
alignment: Alignment.topRight,
onPressed: () async {
final result = await showDialog<bool>(
context: context,
builder: (context) =>
AlertDialog(
title: const Text(
'Some text'),
content: const Text(
'Some text ...'),
actions: [
TextButton(
onPressed: () =>
Navigator.pop(
context, false),
child: const Text('Cancel'),
),
TextButton(
onPressed: () =>
Navigator.pop(
context, true),
child: const Text('Delete'),
),
],
),
);
if (result == null || !result) {
return;
}
deleteList(post.id!, post.loginEmail!);
print('removing postid[$index]');
setState(() {
posts.removeAt(index);
if(posts.isEmpty)
{
const Text("No data to display"); // <---- WHY this text is NOT displayed
}
});
},
iconSize: 20.0,
icon: const Icon(Icons.delete),
),
]
),
),
Expanded(...),
const Expanded(...)
]
),
),
],
),
),
);
}
);
}
>Solution :
You have to check post data empty or not. If post data is empty no need to call buildPosts(snapshot.data!)
. At that time show Simple text or empty UI. please check the fixed code below.
body: Center(
child: FutureBuilder<List<Post>>(
future: postsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator(
backgroundColor: Colors.black,
valueColor: AlwaysStoppedAnimation<Color>(Colors.green)
);
} else if (snapshot.hasData) {
// Store Post data in posts variable
List<Post> posts = snapshot.data??[];
//Check if posts is Empty show No data message.
//posts empty means hav't any post data
if(posts.isEmpty){
return const Text("No data to display");
}
return buildPosts(snapshot.data!);
} else {
return const Text("No data to display");
}
},
),
),
);
Replace your setState with
deleteList(post.id!, post.loginEmail!);
print('removing postid[$index]');
setState(() {
posts.removeAt(index);
});