Cannot refresh list view after delete the row - flutter

When I delete the data on the row, there are no changes after doing the delete, but when I return the menu to the dashboard page and open to the new Customer Data page, the changes are visible. Here I have given setState so that the list view can be refreshed immediately, but after I give setState it still can't be refreshed. And then an error like the following appears.
My problem on link https://youtu.be/gC0P-k-2myw
This is mystatefullwidget.
class DataNasabah extends StatefulWidget {
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
String nama_debitur = '';
List<Nasabah> _nasabah = [];
#override
void initState() {
super.initState();
_loadUserData();
_getNasabah();
}
_loadUserData() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var user = jsonDecode(localStorage.getString('user'));
if (user != null) {
setState(() {
nama_debitur = user['nama_debitur'];
});
}
}
_getNasabah() {
NasabahService.getUser().then((nasabah) {
if (mounted) {
setState(() {
_nasabah = nasabah;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Data Nasabah'),
backgroundColor: Color(0xff151515),
// automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: PaginatedDataTable(
rowsPerPage: 10,
columns: [
DataColumn(
label: Expanded(
child: Text(
'ID Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Nama Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Aksi',
textAlign: TextAlign.center,
)),
),
],
source: NasabahDataTableSource(
userData: _nasabah,
context: context,
onUserDeleted:(){
setState(() {
});
}
),
),
),
);
}
}
class NasabahDataTableSource
class NasabahDataTableSource extends DataTableSource {
BuildContext context;
Function onUserDeleted;
NasabahDataTableSource({this.context, this.userData, this.onUserDeleted});
final List<Nasabah> userData;
#override
DataRow getRow(int index) {
return DataRow.byIndex(
index: index,
cells: [
DataCell(Align(
alignment: Alignment.center,
child: Text(
"${userData[index].id}",
))),
DataCell(Align(
alignment: Alignment.center,
child: Text("${userData[index].nama_debitur}"),
)),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.navigate_next),
color: Colors.blueAccent,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DetailNasabah(
nasabah: userData[index],
),
),
);
},
),
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
showDialog(
context: context,
builder: (context) =>
AlertDialog(
title: Text('Hapus Data Nasabah'),
content: Text(
'Apakah anda yakin ingin menghapus data nasabah ini?'),
actions: [
TextButton(
child: Text('Yes'),
onPressed: () {
NasabahService.deleteUser(userData[index].id);
onUserDeleted();
})
],
),
);
},
)
],
),
),
],
);
}
Full Source Code
class DataNasabah extends StatefulWidget {
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
String nama_debitur = '';
List<Nasabah> _nasabah = [];
#override
void initState() {
super.initState();
_loadUserData();
_getNasabah();
}
_loadUserData() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var user = jsonDecode(localStorage.getString('user'));
if (user != null) {
setState(() {
nama_debitur = user['nama_debitur'];
});
}
}
_getNasabah() {
NasabahService.getUser().then((nasabah) {
if (mounted) {
setState(() {
_nasabah = nasabah;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Data Nasabah'),
backgroundColor: Color(0xff151515),
// automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: PaginatedDataTable(
rowsPerPage: 10,
columns: [
DataColumn(
label: Expanded(
child: Text(
'ID Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Nama Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Aksi',
textAlign: TextAlign.center,
)),
),
],
source: NasabahDataTableSource(
userData: _nasabah,
context: context,
onUserDeleted:(){
setState(() {
});
}
),
),
),
);
}
}
class NasabahDataTableSource extends DataTableSource {
BuildContext context;
Function onUserDeleted;
NasabahDataTableSource({this.context, this.userData, this.onUserDeleted});
final List<Nasabah> userData;
#override
DataRow getRow(int index) {
return DataRow.byIndex(
index: index,
cells: [
DataCell(Align(
alignment: Alignment.center,
child: Text(
"${userData[index].id}",
))),
DataCell(Align(
alignment: Alignment.center,
child: Text("${userData[index].nama_debitur}"),
)),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.navigate_next),
color: Colors.blueAccent,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DetailNasabah(
nasabah: userData[index],
),
),
);
},
),
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
showDialog(
context: context,
builder: (context) =>
AlertDialog(
title: Text('Hapus Data Nasabah'),
content: Text(
'Apakah anda yakin ingin menghapus data nasabah ini?'),
actions: [
TextButton(
child: Text('Yes'),
onPressed: () {
NasabahService.deleteUser(userData[index].id);
onUserDeleted();
})
],
),
);
},
)
],
),
),
],
);
}
i haven't find that solution. Please help.
code snippet
api.dart
deleteData(apiURL, id) async {
var fullUrl = _url + apiURL + '/' + id.toString();
await _getToken();
return await http.delete(
fullUrl,
headers: _setHeaders(),
);
}
nasabah_service
static Future<List<Nasabah>> deleteUser(id) async {
final response = await Network().deleteData(baseUrl, id);
List<Nasabah> list = parseResponse(response.body);
return list;
}

You need to refresh your updated List after delet user.
so we can do
onPressed: () async {
await NasabahService.deleteUser(userData[index].id);
.then((value) async {
await //NasabahService.getUser();
});
},

Related

How to automatically close a dialog box without clicking in flutter?

I have a dialog box, when I click on the Send Again button, I make a request to the server and, if successful, another _emailSentDialog dialog box opens from above. How can I make the first EmailVerifyDialog automatically close when the second _emailSentDialog is opened?
class EmailVerifyDialog extends StatelessWidget {
final CurrentEmailCubit cubit;
const EmailVerifyDialog({Key? key, required this.cubit}) : super(key: key);
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return AlertDialogGradientBorder(
height: size.height * .5,
child: SizedBox(
width: size.width,
child: Padding(
padding: const EdgeInsets.only(bottom: 35),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 45),
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(
children: [
WidgetSpan(
child: FittedBox(
child: Row(
children: [
const Text(
'Didn’t recieve a link? ',
style: constants.Styles.smallBookTextStyleWhite,
),
TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero),
onPressed: () async {
await cubit
.sendConfirmationCode(
email: cubit.currentEmail)
.then((value) => {
if (value)
{
_emailSentDialog(context),
}
else
{
_errorNotification(context),
}
});
log(cubit.currentEmail);
},
child: const Text(
'Send Again',
style: constants
.Styles.smallBookUnderlineTextStyleWhite,
),
),
],
),
),
),
],
),
),
),
],
),
),
),
);
}
void _closeDialog(BuildContext context) {
Navigator.pop(context);
}
void _emailSentDialog(context) async {
showDialog(
context: context,
builder: (BuildContext context) => const EmailSentDialog(),
);
}
I was referring this way
onPressed: () async {
setState(() {
text = "checking on Server";
});
final showSecondDialog = await serverResult();
if (showSecondDialog) {
if (!mounted) return;
Navigator.of(context).pop();
showDialog2(context);
}
},
class TestDialogActivity extends StatefulWidget {
const TestDialogActivity({Key? key}) : super(key: key);
#override
State<TestDialogActivity> createState() => _TestDialogActivityState();
}
class _TestDialogActivityState extends State<TestDialogActivity> {
showDialog2(context) async {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () async {
Navigator.of(context).pop();
},
child: Text(" close Second dialog "))
],
),
),
);
}
Future<bool> serverResult() async {
await Future.delayed(Duration(seconds: 1));
return true;
}
showDialog1(context) async {
String text = "sendAgain";
showDialog(
context: context,
builder: (context) => StatefulBuilder(
builder: (context, setState) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () async {
setState(() {
text = "checking on Server";
});
final showSecondDialog = await serverResult();
if (showSecondDialog) {
if (!mounted) return;
Navigator.of(context).pop();
showDialog2(context);
}
},
child: Text("$text"))
],
),
),
),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => showDialog1(context),
),
);
}
}

The method 'setState' isn't defined for the type 'NasabahDataTableSource'

I want to use setState method in class "NasabahDataTableSource" but when i use setState in this class cannot work and Error: The method 'setState' isn't defined for the class 'NasabahDataTableSource'.
'NasabahDataTableSource' is from 'package:flutter_auth/screens/Menu/DataNasabah/datanasabah.dart' ('lib/screens/Menu/DataNasabah/datanasabah.dart').
Try correcting the name to the name of an existing method, or defining a method named 'setState'.
setState(() {
^^^^^^^^
This is mystatefullwidget.
class DataNasabah extends StatefulWidget {
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
String nama_debitur = '';
List<Nasabah> _nasabah = [];
#override
void initState() {
super.initState();
_loadUserData();
_getNasabah();
}
_loadUserData() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var user = jsonDecode(localStorage.getString('user'));
if (user != null) {
setState(() {
nama_debitur = user['nama_debitur'];
});
}
}
_getNasabah() {
NasabahService.getUser().then((nasabah) {
if (mounted) {
setState(() {
_nasabah = nasabah;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Data Nasabah'),
backgroundColor: Color(0xff151515),
// automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: PaginatedDataTable(
rowsPerPage: 10,
columns: [
DataColumn(
label: Expanded(
child: Text(
'ID Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Nama Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Aksi',
textAlign: TextAlign.center,
)),
),
],
source: NasabahDataTableSource(userData: _nasabah, context: context),
),
),
);
}
}
I want to use setState method in this class.but cann't use.I
comment setState place
class NasabahDataTableSource extends DataTableSource {
BuildContext context;
NasabahDataTableSource({this.context, this.userData});
final List<Nasabah> userData;
#override
DataRow getRow(int index) {
return DataRow.byIndex(
index: index,
cells: [
DataCell(Align(
alignment: Alignment.center,
child: Text(
"${userData[index].id}",
))),
DataCell(Align(
alignment: Alignment.center,
child: Text("${userData[index].nama_debitur}"),
)),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.navigate_next),
color: Colors.blueAccent,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DetailNasabah(
nasabah: userData[index],
),
),
);
},
),
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
showDialog(
context: context,
builder: (context) =>
AlertDialog(
title: Text('Hapus Data Nasabah'),
content: Text(
'Apakah anda yakin ingin menghapus data nasabah ini?'),
actions: [
TextButton(
child: Text('Yes'),
onPressed: () {
NasabahService.deleteUser(userData[index].id);
setState(() {
//Cann't use
});
})
],
),
);
},
)
],
),
),
],
);
}
i haven't find that solution.
Please help.
You can not use setState() without StatefulWidget. I suggest you to use Function to pass your action and notify to rebuild UI using setState(). Need little bit modification on your code.
Add Function parameter to your NasabahDataTableSource.
Function onUserDeleted;
Modify your NasabahDataTableSource constructor.
NasabahDataTableSource({required this.context,required this.userData,required this.onUserDeleted}); // modify your constructor
Replace setState by onUserDeleted inside onPressed.
onUserDeleted(); // call onUserDeleted
//setState(() {
//Cann't use
//});
NasabahDataTableSource full code.
class NasabahDataTableSource extends DataTableSource {
BuildContext context;
Function onUserDeleted; // add onUserDeleted function
final List<Nasabah> userData;
NasabahDataTableSource({required this.context,required this.userData,required this.onUserDeleted}); // modify your constructor
#override
DataRow getRow(int index) {
return DataRow.byIndex(
index: index,
cells: [
DataCell(Align(
alignment: Alignment.center,
child: Text(
"${userData[index].id}",
))),
DataCell(Align(
alignment: Alignment.center,
child: Text("${userData[index].nama_debitur}"),
)),
DataCell(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.navigate_next),
color: Colors.blueAccent,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
DetailNasabah(
nasabah: userData[index],
),
),
);
},
),
IconButton(
icon: Icon(Icons.delete),
color: Colors.red,
onPressed: () {
showDialog(
context: context,
builder: (context) =>
AlertDialog(
title: Text('Hapus Data Nasabah'),
content: Text(
'Apakah anda yakin ingin menghapus data nasabah ini?'),
actions: [
TextButton(
child: Text('Yes'),
onPressed: () {
NasabahService.deleteUser(userData[index].id);
onUserDeleted(); // call onUserDeleted
//setState(() {
//Cann't use
//});
})
],
),
);
},
)
],
),
),
],
);
}
Modify your DataNasabah source by adding onUserDeleted and call setState
source: NasabahDataTableSource(
userData: _nasabah,
context: context,
onUserDeleted:(){
setState((){}); // add setState
}),
DataNasabah full code.
class DataNasabah extends StatefulWidget {
#override
_DataNasabahState createState() => _DataNasabahState();
}
class _DataNasabahState extends State<DataNasabah> {
String nama_debitur = '';
List<Nasabah> _nasabah = [];
#override
void initState() {
super.initState();
_loadUserData();
_getNasabah();
}
_loadUserData() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
var user = jsonDecode(localStorage.getString('user'));
if (user != null) {
setState(() {
nama_debitur = user['nama_debitur'];
});
}
}
_getNasabah() {
NasabahService.getUser().then((nasabah) {
if (mounted) {
setState(() {
_nasabah = nasabah;
});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Data Nasabah'),
backgroundColor: Color(0xff151515),
// automaticallyImplyLeading: false,
),
body: SingleChildScrollView(
child: PaginatedDataTable(
rowsPerPage: 10,
columns: [
DataColumn(
label: Expanded(
child: Text(
'ID Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Nama Nasabah',
textAlign: TextAlign.center,
)),
),
DataColumn(
label: Expanded(
child: Text(
'Aksi',
textAlign: TextAlign.center,
)),
),
],
source: NasabahDataTableSource(
userData: _nasabah,
context: context,
onUserDeleted:(){
setState((){}); // add setState
}),
),
),
);
}
}
you cant setstate in NasabahDataTableSource because not extends StatefulWidget. only stateful who can setstate.
but you can change variable without setstate using getx in stateless.

RangeError (index) Flutter

I am getting an error and red screen while trying to click a button. RangeError (index): Invalid value: Valid value range is empty: 0. I do not know how to fix this error because nothing is flagged until I run my emulator. I have attached my
If I need to add some code please let me know I am more than willing to. Thank you!
home_page.dart
import 'package:flutter/material.dart';
import 'package:timestudy_test/pages/study_page.dart';
import 'package:timestudy_test/pages/timer_page.dart';
import 'package:timestudy_test/viewmodels/study_viewmodel.dart';
class HomePage extends StatefulWidget {
#override
State createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
TextEditingController textController = new TextEditingController();
late String filter;
#override
void initState() {
textController.addListener(() {
setState(() {
filter = textController.text;
});
});
super.initState();
}
#override
void dispose() {
textController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text('TimeStudyApp'),
),
body: Material(
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 8.0, left: 16.0, right: 16.0),
child: TextField(
style: TextStyle(fontSize: 18.0),
decoration: InputDecoration(
prefixIcon: Icon(Icons.search),
suffixIcon: IconButton(
icon: Icon(Icons.close),
onPressed: () {
textController.clear();
FocusScope.of(context).requestFocus(FocusNode());
},
),
hintText: "Search...",
),
controller: textController,
)),
Expanded(
child: StudyViewModel.studies.length > 0
? ListView.builder(
itemCount: StudyViewModel.studies.length,
itemBuilder: (BuildContext context, int index) {
if (filter == null || filter == "") {
return buildRow(context, index);
} else {
if (StudyViewModel.studies[index].name
.toLowerCase()
.contains(filter.toLowerCase())) {
return buildRow(context, index);
} else {
return Container();
}
}
},
)
: Center(
child: Text('No studies found!'),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () async {
int? nullableInterger;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StudyPage(
title: 'Add a study',
selected: nullableInterger ?? 0,
)));
},
),
);
}
Widget buildRow(BuildContext context, int index) {
return ExpansionTile(
title: Text(StudyViewModel.studies[index].name, style: TextStyle(fontSize: 18.0)),
children: <Widget>[
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: StudyViewModel.studies[index].tasks.length,
itemBuilder: (context, int taskIndex) {
return ListTile(
title: Text(StudyViewModel.studies[index].tasks[taskIndex].name),
contentPadding: EdgeInsets.symmetric(horizontal: 32.0),
subtitle: Text(
StudyViewModel.studies[index].tasks[taskIndex].elapsedTime),
trailing: IconButton(
icon: Icon(
Icons.timer
),
onPressed: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TimerPage(
task: StudyViewModel
.studies[index].tasks[taskIndex])));
},
),
);
},
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(
Icons.edit
),
onPressed: () async {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StudyPage(
title: StudyViewModel.studies[index].name,
selected: index)));
},
),
IconButton(
icon: Icon(
Icons.delete
),
onPressed: () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text('Do you wish to delete this study?'),
actions: <Widget>[
FlatButton(
child: Text('Accept'),
onPressed: () async {
StudyViewModel.studies.removeAt(index);
await StudyViewModel.saveFile();
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
},
),
],
),
],
);
}
}
study_page.dart
import 'package:flutter/material.dart';
import 'package:timestudy_test/models/study.dart';
import 'package:timestudy_test/models/task.dart';
import 'package:timestudy_test/viewmodels/study_viewmodel.dart';
class StudyPage extends StatefulWidget {
final String title;
final int selected;
StudyPage({required this.title, required this.selected});
#override
State createState() => StudyPageState();
}
class StudyPageState extends State<StudyPage> {
late Study study;
late TextField nameField;
TextEditingController nameController = new TextEditingController();
late TextField taskNameField;
TextEditingController taskNameController = new TextEditingController();
#override
void initState() {
nameField = new TextField(
controller: nameController,
decoration: InputDecoration(
labelText: 'Study name'),
);
taskNameField = new TextField(
controller: taskNameController,
decoration:
InputDecoration(labelText: 'Task name'),
);
if(widget.selected != null) {
study = StudyViewModel.studies[widget.selected];
nameController.text = study.name;
} else {
study = new Study(
name: "",
tasks: <Task>[]
);
}
super.initState();
}
#override
void dispose() {
nameController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(
title: Text(widget.title),
),
body: Material(
child: Padding(padding: EdgeInsets.all(16.0), child: Column(
children: <Widget>[
Padding(padding: EdgeInsets.only(bottom: 8.0), child: nameField),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text('Tasks:', style: TextStyle(fontSize: 18.0),),
IconButton(
icon: Icon(Icons.add),
onPressed: () async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Add a task'),
content: taskNameField,
actions: <Widget>[
FlatButton(
child: Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
FlatButton(
child: Text('Accept'),
onPressed: () {
if(taskNameController.text == ""){
errorDialog(context, 'Please enter a task name!');
} else {
setState(() {
study.tasks.add(new Task(
name: taskNameController.text,
elapsedTime:
StudyViewModel.milliToElapsedString(
0)));
taskNameController.clear();
});
Navigator.of(context).pop();
}
},
),
],
);
});
},
)
],
),
Expanded(
child: ListView.builder(
itemCount: study.tasks.length,
itemBuilder: (context, int index) {
return ListTile(
title: Text(study.tasks[index].name),
trailing: IconButton(
icon: Icon(Icons.delete),
onPressed: () {
setState(() {
study.tasks.removeAt(index);
});
},
),
);
},
),
), Spacer(),
Center(
child: RaisedButton(
color: Theme.of(context).accentColor,
child: Text('Save'),
onPressed: () async {
if (nameController.text == "") {
errorDialog(context, 'Please enter a study name!');
} else {
if (study.tasks.length < 1) {
errorDialog(context, 'Please add at least one task!');
} else {
study.name = nameController.text;
if (widget.selected != null) {
StudyViewModel.studies[widget.selected] = study;
await StudyViewModel.saveFile();
Navigator.of(context).pop();
} else {
if (StudyViewModel.checkName(nameController.text)) {
errorDialog(context, 'Study name already taken!');
} else {
StudyViewModel.studies.add(study);
await StudyViewModel.saveFile();
Navigator.of(context).pop();
}
}
}
}
},
))
],
),
)));
}
void errorDialog(BuildContext context, String message) async {
await showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(message),
actions: <Widget>[
FlatButton(
child: Text('Close'),
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
}
);
}
}
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () async {
int? nullableInterger;
// the issue is here you need to assign value
// the nullableInterger is use here as nothing.. declare it on state level and
// assign it when your listview builder done so the value of nullable integer is
// changed and passing value as argument will not be 0 and this error will not appear again
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => StudyPage(
title: 'Add a study',
selected: nullableInterger ?? 0,
)));
},
),

Flutter navigate List tile to a list detail page

have a to do app which lists all todos in in a screen
This is my listview
class assignedTask extends StatefulWidget {
static const String id = 'assignedTask';
#override
_assignedTaskState createState() => _assignedTaskState();
}
class _assignedTaskState extends State<assignedTask> {
String Title;
String Summary;
var tasks;
crudMedthods crudObj = new crudMedthods();
var documentID;
var documents;
Future<bool> addDialog(BuildContext context) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add Data', style: TextStyle(fontSize: 15.0)),
content: Container(
height: 125.0,
width: 150.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Enter Title'),
onChanged: (value) {
this.Title = value;
},
),
SizedBox(height: 5.0),
TextField(
decoration: InputDecoration(hintText: 'Enter Summary'),
onChanged: (value) {
this.Summary = value;
},
),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Add'),
textColor: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
crudObj.addData({
'Title': this.Title,
'Summary': this.Summary
}).then((result) {
dialogTrigger(context);
}).catchError((e) {
print(e);
});
},
)
],
);
});
}
Future<bool> updateDialog(BuildContext context, selectedDoc) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Update Data', style: TextStyle(fontSize: 15.0)),
content: Container(
height: 125.0,
width: 150.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Title'),
onChanged: (value) {
this.Title = value;
},
),
SizedBox(height: 5.0),
TextField(
decoration: InputDecoration(hintText: 'Enter Summary'),
onChanged: (value) {
this.Summary = value;
},
),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Update'),
textColor: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
crudObj.updateData(selectedDoc, {
'Title': this.Title,
'Summary': this.Summary
}).then((result) {
// dialogTrigger(context);
}).catchError((e) {
print(e);
});
},
)
],
);
});
}
Future<bool> dialogTrigger(BuildContext context) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Job Done', style: TextStyle(fontSize: 15.0)),
content: Text('Added'),
actions: <Widget>[
FlatButton(
child: Text('Alright'),
textColor: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
}
#override
void initState() {
crudObj.getData().then((results) {
setState(() {
tasks = results;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Assigned Tasks'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
addDialog(context);
},
),
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
crudObj.getData().then((results) {
setState(() {
tasks = results;
});
});
},
)
],
),
body: _TaskList(),
);
}
Widget _TaskList() {
if (tasks != null) {
return StreamBuilder(
stream: tasks,
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.data != null) {
return ListView.builder(
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(7.0),
itemBuilder: (context, i) {
return ListTile(
title: Text(snapshot.data.documents[i].data["Title"]??""),
subtitle: Text(snapshot.data.documents[i].data["Summary"]??""),
/*onTap: () {
*//*
updateDialog(
context, snapshot.data.documents[i].documentID);
},*/
onTap: (){
Navigator.push(context,MaterialPageRoute(builder:(context)=>detailview(context,snapshot.data.douments[i].documentid)));
},
onLongPress: () {
crudObj.deleteData(snapshot.data.documents[i].documentID);
},
);
},
);
}
return CircularProgressIndicator();
},
);
} else {
return Text('Loading, Please wait..');
}
}
}
When i press ontap it should go to the detail page which shows details of only that particular task(note: i now have only the values Title and summary for now, i will add rest later they should show in the detail page)
My detailview is as follows
class detailview extends StatefulWidget {
static const String id = 'detailview';
detailview(BuildContext context, selectedDoc);
#override
_detailviewState createState() => _detailviewState();
}
class _detailviewState extends State<detailview> {
final TaskReference = FirebaseDatabase.instance.reference().child('Task');
crudMedthods crudObj1 = new crudMedthods();
/*TextEditingController _titleController;
TextEditingController _descriptionController;*/
var tasks;
/*#override
void initState() {
super.initState();
//_titleController = new TextEditingController(text: widget.tasks.Title);
//_descriptionController = new TextEditingController(text: widget.tasks.Summary);
}*
*/
#override
void initState() {
crudObj1.getDetail(tasks).then((results) {
setState(() {
tasks = results;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Details of Tasks'),
actions: <Widget>[
],
),
body: Column(
children: <Widget>[
TextField(
//controller: _titleController,
),
],
)
);
}
}
How could i access the values of particular tapped value in detail page.
Just pass the DocumentSnapshot to your detail page like this:
onTap: (){
Navigator.push(context,MaterialPageRoute(builder:(context)=>DetailPage(context,snapshot.data.douments[i])));
},
In your detail page receive the DocumentSnapshot and access anything you are getting from it.
class DetailPage extends StatelessWidget {
DocumentSnapshot detailDocument;
DetailPage(this.detailDocument);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(detailDocument.data["Title"]),
),
body: Center(
child: Text(detailDocument.data["Summary"]),
),
);
}
}

Class <QuerySnapshot> has no instance getter 'documents'.Reciever : Instance of 'QuerySnapshot'

I have a to do app which lists all todos in in a screen
This is my listview
class assignedTask extends StatefulWidget {
static const String id = 'assignedTask';
#override
_assignedTaskState createState() => _assignedTaskState();
}
class _assignedTaskState extends State<assignedTask> {
String Title;
String Summary;
var tasks;
crudMedthods crudObj = new crudMedthods();
var documentID;
var documents;
Future<bool> addDialog(BuildContext context) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Add Data', style: TextStyle(fontSize: 15.0)),
content: Container(
height: 125.0,
width: 150.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Enter Title'),
onChanged: (value) {
this.Title = value;
},
),
SizedBox(height: 5.0),
TextField(
decoration: InputDecoration(hintText: 'Enter Summary'),
onChanged: (value) {
this.Summary = value;
},
),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Add'),
textColor: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
crudObj.addData({
'Title': this.Title,
'Summary': this.Summary
}).then((result) {
dialogTrigger(context);
}).catchError((e) {
print(e);
});
},
)
],
);
});
}
Future<bool> updateDialog(BuildContext context, selectedDoc) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Update Data', style: TextStyle(fontSize: 15.0)),
content: Container(
height: 125.0,
width: 150.0,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextField(
decoration: InputDecoration(hintText: 'Title'),
onChanged: (value) {
this.Title = value;
},
),
SizedBox(height: 5.0),
TextField(
decoration: InputDecoration(hintText: 'Enter Summary'),
onChanged: (value) {
this.Summary = value;
},
),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('Update'),
textColor: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
crudObj.updateData(selectedDoc, {
'Title': this.Title,
'Summary': this.Summary
}).then((result) {
// dialogTrigger(context);
}).catchError((e) {
print(e);
});
},
)
],
);
});
}
Future<bool> dialogTrigger(BuildContext context) async {
return showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('Job Done', style: TextStyle(fontSize: 15.0)),
content: Text('Added'),
actions: <Widget>[
FlatButton(
child: Text('Alright'),
textColor: Colors.blue,
onPressed: () {
Navigator.of(context).pop();
},
)
],
);
});
}
#override
void initState() {
crudObj.getData().then((results) {
setState(() {
tasks = results;
});
});
super.initState();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
title: Text('Assigned Tasks'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.add),
onPressed: () {
addDialog(context);
},
),
IconButton(
icon: Icon(Icons.refresh),
onPressed: () {
crudObj.getData().then((results) {
setState(() {
tasks = results;
});
});
},
)
],
),
body: _TaskList(),
);
}
Widget _TaskList() {
if (tasks != null) {
return StreamBuilder(
stream: tasks,
// ignore: missing_return
builder: (context, snapshot) {
if (snapshot.data != null) {
return ListView.builder(
itemCount: snapshot.data.documents.length,
padding: EdgeInsets.all(7.0),
itemBuilder: (context, i) {
return ListTile(
title: Text(snapshot.data.documents[i].data["Title"]??""),
subtitle: Text(snapshot.data.documents[i].data["Summary"]??""),
/*onTap: () {
*//*
updateDialog(
context, snapshot.data.documents[i].documentID);
},*/
onTap: (){
Navigator.push(context,MaterialPageRoute(builder:(context)=>DetailPage(snapshot.data.douments[i])));
}, onLongPress: () {
crudObj.deleteData(snapshot.data.documents[i].documentID);
},
);
},
);
}
return CircularProgressIndicator();
},
);
} else {
return Text('Loading, Please wait..');
}
}
}
When i press ontap it should go to the detail page which shows details of only that particular task(note: i now have only the values Title and summary for now, i will add rest later they should show in the detail page)
My detailview is as follows
class DetailPage extends StatelessWidget {
DocumentSnapshot detailDocument;
DetailPage(this.detailDocument);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text( detailDocument.data["Title"]),
),
body: Center(
child: Text(detailDocument.data["Summary"]),
),
);
}
}
I am getting an error
The following NoSuchMethodError was thrown building Builder(dirty):
Class 'QuerySnapshot' has no instance getter 'douments'.
Receiver: Instance of 'QuerySnapshot'
Tried calling: douments
The relevant error-causing widget was:
MaterialApp file:///C:/Users/TRICON/AndroidStudioProjects/taskmanager/lib/main.dart:21:14
When the exception was thrown, this was the stack:
0 Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
1 _assignedTaskState._TaskList.... (package:taskmanager/screens/assignedtask.dart:208:106)
You are using
Navigator.push(context,MaterialPageRoute(builder:(context)=>DetailPage(snapshot.data.douments[i])));
instead of
Navigator.push(context,MaterialPageRoute(builder:(context)=>DetailPage(snapshot.data.documents[i])));
It's just a difference in the spelling of douments as documents.