how to solve flutter sqlite syntax error? - database

bi
I making database with sqlite
I was building a database and I had a problem.
That my screen full code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math';
import 'package:socialapp/model/todo.dart';
import 'package:socialapp/widgets/database_create.dart';
class writeprofile2 extends StatefulWidget {
writeprofile2({Key key}) : super(key : key);
#override
_writeprofile2State createState() => _writeprofile2State();
}
class _writeprofile2State extends State<writeprofile2> {
final _formKey = GlobalKey<FormState>();
String _name, _age, _intro;
#override
Widget build(BuildContext context) {
return Scaffold(
body: Builder(
builder: (context) => Center(
child: Container(
child: Container(
child: Form(
key: _formKey,
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 70),
child: Text(
'프로필 작성',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w500,
),
),
),
Padding(
padding: EdgeInsets.only(top: 10, bottom: 50),
child: Container(
height: 1,
width: MediaQuery.of(context).size.width / 1.4,
color: Colors.black26,
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Container(
//이름입력
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 20,
alignment: FractionalOffset.center,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius:
BorderRadius.all(const Radius.circular(20)),
),
child: TextFormField(
decoration: InputDecoration(
hintStyle: TextStyle(
fontSize: 20,
),
border: InputBorder.none,
hintText: '이름',
prefixIcon: Icon(
Icons.person_outline,
color: Colors.black,
),
),
validator: (input) {
if (input.isEmpty) {
return '이름을 입력해주세요';
}
},
onSaved: (value)=> _name = value,
),
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Container(
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 20,
alignment: FractionalOffset.center,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius:
BorderRadius.all(const Radius.circular(20)),
),
child: TextFormField(
keyboardType: TextInputType.number,
inputFormatters: [
WhitelistingTextInputFormatter.digitsOnly
],
decoration: InputDecoration(
hintStyle: TextStyle(
fontSize: 20,
),
border: InputBorder.none,
hintText: '나이',
prefixIcon: Icon(
Icons.label_outline,
color: Colors.black,
),
),
validator: (val) {
if (!isNumber(val)) {
return "나이를 입력해주세요";
};
},
onSaved: (value)=> _age = value,
),
),
),
Padding(
padding: EdgeInsets.only(top: 10),
child: Container(
//이름입력
width: MediaQuery.of(context).size.width / 2,
height: MediaQuery.of(context).size.height / 20,
alignment: FractionalOffset.center,
decoration: BoxDecoration(
color: Colors.black12,
borderRadius:
BorderRadius.all(const Radius.circular(20)),
),
child: TextFormField(
decoration: InputDecoration(
hintStyle: TextStyle(
fontSize: 20,
),
border: InputBorder.none,
hintText: '소개',
prefixIcon: Icon(
Icons.person_outline,
color: Colors.black,
),
),
validator: (input) {
if (input.isEmpty) {
return '자기소개';
}
},
onSaved: (value)=> _intro = value,
),
),
),
InkWell(
onTap: (){
Todo newtodo = Todo(name: _name, age: _age, intro: _intro);
DBHelper().createData(newtodo);
setState(() {
});
},
child: Padding(
padding: EdgeInsets.only(top: 50),
child: Container(
width: MediaQuery.of(context).size.width / 3,
height: MediaQuery.of(context).size.height / 20,
alignment: FractionalOffset.center,
decoration: BoxDecoration(
color: const Color.fromRGBO(250, 80, 100, 1),
borderRadius:
BorderRadius.all(const Radius.circular(30)),
),
child: Text(
"Next",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.w500,
letterSpacing: 0.3,
),
),
),
),
),
],
),
),
),
),
),
),
);
}
String randomTodo(){
final randomNumber = Random().nextInt(4);
String todo;
switch(randomNumber){
case 1:
todo = 'hello1';
break;
case 1:
todo = 'hello2';
break;
case 1:
todo = 'hello3';
break;
default:
todo = 'default';
break;
}
return todo;
}
}
bool isNumber(String valueNumber) {
if (valueNumber == null) {
return true;
}
final n = num.tryParse(valueNumber);
return n != null;
}
That my todo Code :
class Todo {
int id;
String name;
String intro;
String age;
Todo({
this.id,
this.name,
this.intro,
this.age,});
factory Todo.fromJson(Map<String, dynamic> json) => Todo(
id: json["id"],
intro: json["intro"],
name: json["name"],
age: json["age"],
);
Map<String, dynamic> toJson() =>
{
'id' :id,
'name': name,
'age': age,
'intro' : intro,
};
}
That database create code:
import 'package:path_provider/path_provider.dart';
import 'package:sqflite/sqflite.dart';
import 'package:socialapp/model/todo.dart';
import 'dart:async';
import 'dart:io';
import 'package:path/path.dart';
final String tableName = 'person';
class DBHelper{
DBHelper._();
static final DBHelper _db = DBHelper._();
factory DBHelper() => _db;
//해당 변수에 데이터베이스 정보 저장
static Database _database;
Future<Database> get database async{
if(_database != null)return _database;
_database = await initDB();
return _database;
}
initDB() async{
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(documentsDirectory.path, 'PersonProfile.db');
return await openDatabase(
path,
version: 1,
onOpen: (db) {},
onCreate: (Database db, int version) async{
await db.execute('''
CREATE TABLE $tableName
id INTEGER PRIMARY KEY,
name TEXT,
intro TEXT,
age TEXT ''');
},
);
}
createData(Todo todo)async{
final db = await database;
var res = await db.insert(tableName, todo.toJson());
return res;
}
//read
getTodo(int id) async{
final db = await database;
var res = await db.query(tableName, where: 'id = ?', whereArgs: [id]);
return res.isNotEmpty ? Todo.fromJson(res.first) : Null;
}
// getAllTodos() async{
// final db = await database;
// var res = await db.query(tableNam
// }
updateTodo(Todo todo) async{
final db = await database;
var res = await db.update(tableName, todo.toJson(),
where: 'id =?' , whereArgs: [todo.id]);
return res;
}
//Delete
deleteTodo(int id) async{
final db = await database;
db.delete(tableName, where: 'id =?', whereArgs: [id]);
}
deleteAllTodos() async{
final db =await database;
db.rawDelete("Delete * from $tableName");
}
}
error code :
>
>
> id INTEGER PRIMARY KEY,
> name TEXT,
> intro TEXT,
> age TEXT flutter: error DatabaseException(Error Domain=FMDatabase Code=1 "near "id": syntax error"
> UserInfo={NSLocalizedDescription=near "id": syntax error}) sql '
> CREATE TABLE person
> id INTEGER PRIMARY KEY,
> name TEXT,
> intro TEXT,
> age TEXT ' args []} during open, closing... [VERBOSE-2:ui_dart_state.cc(148)] Unhandled Exception:
> DatabaseException(Error Domain=FMDatabase Code=1 "near "id": syntax
> error" UserInfo={NSLocalizedDescription=near "id": syntax error}) sql
> ' CREATE TABLE person
> id INTEGER PRIMARY KEY,
> name TEXT,
> intro TEXT,
> age TEXT ' args []}
> #0 wrapDatabaseException (package:sqflite/src/exception_impl.dart:11:7) <asynchronous
> suspension>
> #1 SqfliteDatabaseFactoryImpl.wrapDatabaseException (package:sqflite/src/factory_impl.dart:29:7)
> #2 SqfliteDatabaseMixin.safeInvokeMethod (package:sqflite/src/database_mixin.dart:184:15)
> #3 SqfliteDatabaseMixin.invokeExecute (package:sqflite/src/database_mixin.dart:342:12)
> #4 SqfliteDatabaseMixin.txnExecute.<anonymous closure> (package:sqflite/src/database_mixin.dart:334:14)
> #5 SqfliteDatabaseMixin.txnSynchronized (package:sqflite/src/database_mixin.dart:285:26) <asynchronous
> suspension>
> #6 SqfliteDatabaseMixin.txnWriteSynchronized (package:sqflite/src/da<…>
How can i fix this ?

You need to add parenthesis after the tableName:
CREATE TABLE $tableName(
id INTEGER PRIMARY KEY,
name TEXT,
intro TEXT,
age TEXT)
Check here:
http://www.mysqltutorial.org/mysql-create-table/
Also check the example in the sqflite plugin:
await db.execute(
'CREATE TABLE Test (id INTEGER PRIMARY KEY, name TEXT, value INTEGER, num REAL)');
});

Related

Problem with Navigation (Error: Range Error (index): Index out of range: no indicies are valid:0)

When i am update some field then it updated successfully and redirect on detail Page but it give following error to me when redirect: Range Error index out of range:no indices are valid:0. I cannot get what is the problem in my code.Please guide me about it. I am attaching my code here,
AppointmentDetailEditPage
class AppointmentDetailsEditPage extends StatefulWidget {
final int aptId;
final int docID;
final int staffId;
final String dTitle;
final int tNo;
final String aptExecutive;
AppointmentDetailsEditPage(
this.aptId,
this.docID,
this.staffId,
this.dTitle,
this.tNo,
// this.doctitle,
// this.docToken,
this.aptExecutive);
#override
_AppointmentDetailsEditPageState createState() =>
_AppointmentDetailsEditPageState(this.aptId, this.docID, this.staffId,
this.dTitle, this.tNo, this.aptExecutive);
}
class _AppointmentDetailsEditPageState
extends State<AppointmentDetailsEditPage> {
var paymentMode = ["Online", "Cash", "Cheque"];
String? selectedMode;
var items = ["Owner", "Tenant", "Agent", "Both"];
var status = ["Open", "Closed", "Cancel"];
TextStyle style = const TextStyle(fontFamily: 'Montserrat', fontSize: 6.0);
AppointmentController appointmentController =
Get.put(AppointmentController());
late Future<Appointment> futureAppointments;
late final int aptId;
late final int docID;
late final int staffId;
late final String dTitle;
late final int tNo;
final String aptExecutive;
List<Appointment> aptmnt = [];
_AppointmentDetailsEditPageState(
this.aptId,
this.docID,
this.staffId,
this.dTitle,
this.tNo,
this.aptExecutive,
);
#override
void initState() {
super.initState();
futureAppointments =
AppointmentController.fetchAppointmentsById(this.aptId);
init();
}
Future init() async {
print('apt ID $aptId');
final aptmnt = await AppointmentController.fetchAppointments;
setState(() {
this.aptmnt = aptmnt as List<Appointment>;
print(aptmnt);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 3, 87, 156),
title: Text('Edit Appointment'),
// flexibleSpace: LogOut(),
leading: IconButton(
icon: BackButtonIcon(),
onPressed: () => Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => AppointmentDetails(
aptId, docID, staffId, dTitle, tNo, aptExecutive)))),
),
body:
//SafeArea(
Center(
child: SafeArea(
child: SingleChildScrollView(
child: Container(
alignment: Alignment.center,
child: FutureBuilder<Appointment>(
future: futureAppointments,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasData) {
return Form(
key: _formKey,
child: Padding(
padding: const EdgeInsets.all(7),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(
// height: 80.0,
width:
MediaQuery.of(context).size.width *
0.4,
child: TypeAheadField<UserLogin>(
hideSuggestionsOnKeyboardHide: true,
textFieldConfiguration:
TextFieldConfiguration(
decoration: InputDecoration(
errorStyle: const TextStyle(
fontSize: 0.05),
fillColor: Color.fromARGB(
255, 233, 246, 252),
// prefixIcon: Icon(Icons.search),
suffixIcon: GestureDetector(
child: Icon(
Icons.close,
color: Color.fromARGB(
137, 221, 221, 221),
size: 20,
),
onTap: () {
aptExecutiveController
.clear();
FocusScope.of(context)
.requestFocus(
FocusNode());
},
),
border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(10.0),
),
hintText:
'Appointment Executive ',
// labelText: 'Appointment Executive',
hintStyle:
TextStyle(fontSize: 12),
),
controller: aptExecutiveController =
TextEditingController(
text:
'${this.aptExecutive}'),
),
suggestionsCallback: (pattern) async {
return await LoginController
.users();
},
itemBuilder:
(context, UserLogin? allUsers) {
final user = allUsers!;
return ListTile(
title: Text(user.userName),
);
},
noItemsFoundBuilder: (context) =>
Container(
height: 50,
child: Center(
child: Text(
'No Staff Found.',
style: TextStyle(fontSize: 12),
),
),
),
onSuggestionSelected:
(UserLogin? AllUsers) {
final user = AllUsers!;
this.aptExecutiveController.text =
user.userName;
setState(() {
this.staffid = user.userId;
// this.staffid = user.userId;
// print('$staffid');
print('$staffid');
// aptExecutive;
});
},
),
),
Navigator.of(context).push(
MaterialPageRoute(
builder:
(BuildContext context) =>
AppointmentDetails(
aptId,
docID,
staffId,
dTitle,
tNo,
aptExecutive)));
AppointmentController
import 'dart:convert';
import 'dart:ui';
import 'package:AtDocHUB/Model/Appointment.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
import 'dart:async';
class AppointmentController {
// fetch list of appointment
static FutureOr<Iterable<Appointment>> fetchAppointments(String title) async {
// final url = Uri.parse('http://192.168.0.134:8080/AtdochubJ-3/appointment/');
final url = Uri.parse(
'http://3.108.194.111:8080/AtdochubJ-3/appointment/appointmentdetails'
// 'http://3.108.194.111:8080/AtdochubJ-3/appointment/appointmentdetails'
);
final response = await http.get(url);
if (response.statusCode == 200) {
final List docs = json.decode(response.body);
return docs.map((json) => Appointment.fromJson(json)).where((doc) {
final titleLower = doc.docTitle.toLowerCase();
final tokenLower = doc.tokenNo.toString();
final searchLower = title.toLowerCase();
return titleLower.contains(searchLower) ||
tokenLower.contains(searchLower);
}).toList();
} else {
throw Exception();
}
}
//list of appointment
static Future<List<Appointment>> fetchAppointmentList() async {
final response = await http.get(Uri.parse(
'http://3.108.194.111:8080/AtdochubJ-3/appointment/appointmentdetails'));
//print(fromJson(json)).toList());
if (response.statusCode == 200) {
final parsed = json.decode(response.body).cast<Map<String, dynamic>>();
return parsed
.map<Appointment>((json) => Appointment.fromJson(json))
.toList();
//return Document.fromJson(jsonDecode(response.body));
} else {
throw Exception('Failed to load Appointment');
}
}
//fetch list of appointment by id
static Future<Appointment> fetchAppointmentsById(aptId) async {
final response = await http.get(
Uri.parse(
'http://3.108.194.111:8080/AtdochubJ-3/appointment/find/${aptId}'),
);
if (response.statusCode == 200) {
return Appointment.fromJson(jsonDecode(response.body)[0]);
} else {
throw Exception('Failed to load Appointment');
}
}
Future<Appointment> createAppointment(
int? aptId,
int? docId,
int staffId,
//String docTitle,
// String tokenNo,
String partyName,
String contactNo,
String partyType,
String aptPlace,
String city,
int? feesCollected,
int totalFees,
String paymentMode,
String aptDate,
String aptTime,
// String aptExecutive,
String aptStatus,
String comments,
// String createdAt,
) async {
final response = await http.put(
// Uri.parse('http://192.168.0.134:8080/AtdochubJ-3/appointment/register'),
Uri.parse('http://3.108.194.111:8080/AtdochubJ-3/appointment/register'
// 'http://3.108.194.111:8080/AtdochubJ-3/appointment/register'
),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
},
body: jsonEncode(<String, dynamic>{
'aptId': aptId,
'docId': docId,
'staffId': staffId,
'partyName': partyName,
'contactNo': contactNo,
'partyType': partyType,
'aptPlace': aptPlace,
'city': city,
'feesCollected': feesCollected!,
'totalFees': totalFees,
'paymentMode': paymentMode,
'aptDate': aptDate,
'aptTime': aptTime,
//'aptExecutive': aptExecutive,
'aptStatus': aptStatus,
'comments': comments,
// 'createdAt': createdAt,
}));
if (response.statusCode == 200 || response.statusCode == 201) {
return Appointment.fromJson(jsonDecode(response.body)[0]);
else{
throw Exception(' Failed To Create Appointment');
}
AppointmentDetailPage
class AppointmentDetails extends StatefulWidget {
final int aptId;
final int staff_Id;
late final int docID;
final String dTitle;
final int tNo;
final String aptExecutive;
// final String doctitle;
// final String docToken;
AppointmentDetails(this.aptId, this.staff_Id, this.docID, this.dTitle,
this.tNo, this.aptExecutive);
#override
_AppointmentDetailsState createState() => _AppointmentDetailsState(
this.aptId,
this.staff_Id,
this.docID,
this.dTitle,
this.tNo,
this.aptExecutive,
);
}
class _AppointmentDetailsState extends State<AppointmentDetails> {
AppointmentController appointmentController =
Get.put(AppointmentController());
late Future<Appointment> futureAppointments;
final int aptId;
final int staff_Id;
final int docID;
final String dTitle;
final int tNo;
final String aptExecutive;
_AppointmentDetailsState(this.aptId, this.staff_Id, this.docID, this.dTitle,
this.tNo, this.aptExecutive);
#override
void initState() {
super.initState();
// print('detail staff ID $staff_Id');
// print('detail doc ID $docId');
print('apt detail...... $aptId, $dTitle, $tNo, $aptExecutive');
futureAppointments =
AppointmentController.fetchAppointmentsById(this.aptId);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Color.fromARGB(255, 3, 87, 156),
title: Text('Appointment Details'),
leading: IconButton(
icon: BackButtonIcon(),
onPressed: () => Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => AppointmentPageFE()))),
),
body: Center(
child: FutureBuilder<Appointment>(
future: futureAppointments,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView(children: [
SafeArea(
child: SingleChildScrollView(
child: Container(
padding: EdgeInsets.all(15),
height: 750,
child: SelectionArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Document Title: ' + this.dTitle,
style: const TextStyle(fontSize: 15.0)),
Text('Token No :' + this.tNo.toString(),
style: const TextStyle(fontSize: 15.0)),
Text("Party Name : " + snapshot.data!.partyName,
style: const TextStyle(fontSize: 15.0)),
Text(
'Appointment Executive :' + this.aptExecutive,
style: const TextStyle(fontSize: 15.0)),
Text("Contact No : " + snapshot.data!.contactNo,
style: const TextStyle(fontSize: 15.0)),
Text("Party Type : " + snapshot.data!.partyType,
style: const TextStyle(fontSize: 15.0)),
Text(
"Appointment Place : " +
snapshot.data!.aptPlace,
style: const TextStyle(fontSize: 15.0)),
Text("Appointment City : " + snapshot.data!.city,
style: const TextStyle(fontSize: 15.0)),
Text(
"Appointment Date : " +
snapshot.data!.aptDate,
style: const TextStyle(fontSize: 15.0)),
Text(
"Appointment Time : " +
snapshot.data!.aptTime,
style: const TextStyle(fontSize: 15.0)),
Text(
"Appointment Status : " +
snapshot.data!.aptStatus,
style: const TextStyle(fontSize: 15.0)),
Text(
"Fees : " +
snapshot.data!.totalFees.toString(),
style: const TextStyle(fontSize: 15.0)),
Text(
"Fees Collected : " +
snapshot.data!.feesCollected.toString(),
style: const TextStyle(fontSize: 15.0)),
Text(
"Payment Mode : " +
snapshot.data!.paymentMode,
style: const TextStyle(fontSize: 15.0)),
Text("Comments : " + snapshot.data!.comments,
style: const TextStyle(fontSize: 15.0)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
alignment: Alignment.center,
height: 35,
width: 200,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color.fromARGB(255, 3, 89, 168),
),
child: TextButton(
// style:
// TextButton.styleFrom(fixedSize: Size.fromHeight(300)),
child: const Text(
'Edit ',
style: TextStyle(
fontSize: 17.0,
fontWeight: FontWeight.bold,
color: Colors.white,
backgroundColor:
Color.fromARGB(255, 3, 89, 168),
),
),
onPressed: () {
print(
'apt executive.......${aptExecutive}');
Navigator.of(context)
.pushAndRemoveUntil(
MaterialPageRoute(
builder: (BuildContext
context) =>
AppointmentDetailsEditPage(
this.aptId,
this.staff_Id,
this.docID,
this.dTitle,
this.tNo,
this.aptExecutive,
)),
(Route<dynamic> route) =>
false);
},
),
),
],
),
]),
),
),
// ),
padding: const EdgeInsets.all(10),
),
),
]);
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
},
),
),
);
}
}

I want to access the single document from firebase and use it show the data and update it

I was trying to get the single doc data from firebase and wanted to update
'''
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_neumorphic/flutter_neumorphic.dart';
import 'package:wallet_app/utils/custom_textfield.dart';
import '../module/firebase_data.dart';
import '../utils/utilts.dart';
class EditPage extends StatefulWidget {
const EditPage({
Key? key,
required this.docId,
}) : super(key: key);
final String docId;
#override
State<EditPage> createState() => _EditPageState();
}
class _EditPageState extends State<EditPage> {
late DocumentSnapshot data;
Future getData() async {
User? user = FirebaseAuth.instance.currentUser;
await FirebaseFirestore.instance
.collection('users')
.doc(user?.uid)
.collection('transactions')
.doc(widget.docId)
.get()
.then((value) => data = value);
}
#override
Widget build(BuildContext context) {
TextEditingController titleController =
TextEditingController(text: data['title']);
TextEditingController amountController =
TextEditingController(text: data['amount'].toString());
TextEditingController descriptionController =
TextEditingController(text: data['description']);
bool income = data['type'];
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
foregroundColor: Colors.grey.shade800,
elevation: 0,
centerTitle: true,
title: const Text(
'Edit Transaction',
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
),
body: FutureBuilder(
future: getData(),
builder: (context, snapshot) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CustomTextfield(
hintText: 'Title', controller: titleController),
CustomTextfield(
hintText: 'Amount',
controller: amountController,
keyBoradType: TextInputType.number,
),
CustomTextfield(
hintText: 'Description',
controller: descriptionController,
miniLines: 4,
maxLines: 10),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Expense',
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18),
),
Switch(
activeColor: Colors.green.shade300,
inactiveTrackColor: Colors.red.shade300,
inactiveThumbColor: Colors.red.shade100,
value: income,
onChanged: (v) {
setState(() {
income = v;
});
}),
const Text(
'Income',
style: TextStyle(
fontWeight: FontWeight.w500, fontSize: 18),
),
],
),
NeumorphicButton(
margin: const EdgeInsets.only(top: 15),
style: NeumorphicStyle(
shape: NeumorphicShape.flat,
color: Colors.grey.shade800,
depth: 6,
),
onPressed: () async {
if (titleController.text.isEmpty &&
amountController.text.isEmpty) {
Utils.showError(message: 'Please fill all the fields');
return;
} else {
FireData()
.updateTransaction(
title: titleController.text,
description: descriptionController.text,
amount: double.parse(amountController.text),
type: income,
docId: widget.docId)
.then((value) => {
if (income == true)
{
Utils.showError(
message: 'Income Edited Successfully')
}
else
{
Utils.showError(
message:
'Expense Edited Successfully')
},
titleController.clear(),
descriptionController.clear(),
amountController.clear(),
income = false,
});
Navigator.pop(context);
}
},
child: const Text(
'Edit Transaction',
style: TextStyle(
fontSize: 20,
color: Colors.white,
fontWeight: FontWeight.w500,
),
),
),
TextButton(onPressed: () => data, child: const Text('data'))
],
),
);
}),
);
}
}
'''
I want to update the data note I am using setState function to update the state of the slider but its not updating. I want to show the available data and then allow to update it.
I also tried to get the data from the previous page but I even got stuck in that if.
I can get the Data from previous page if there's any solution for that also we will try that method.

firestore.set does not save the data in firestore. cannot get a field on a DocumentSnapshotPlatform which does not exist

I use firestore to save the data. So, I use 'set'method. but It can't save the data. I get the error cannot get a field on a DocumentSnapshotPlatform which does not exist. How can I solve this error?
this my code. first code is input the title and content code. '''
class WritePage extends StatefulWidget {
#override
_WritePageState createState() => _WritePageState();
}
class _WritePageState extends State<WritePage> {
DataBase dataBase = new DataBase();
String title = ' '; //제목
String content = ' '; //내용
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text("글쓰기"),
),
body: Center(
child: ListView(
children: <Widget>[
Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 5),
child: TextField(
onChanged: (String text) {
if(text != null) {
title = text;
}else{title = 'null';}
},
keyboardType: TextInputType.multiline,
decoration: InputDecoration(
hintText: '제목을 적어주세요',
border: OutlineInputBorder(),
labelText: "제목을 입력하세요.",
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 20, 20, 5),
child: TextField(
onChanged: (String text) {
if(text != null) {
content = text;
}else{content = 'null';}
},
keyboardType: TextInputType.multiline,
maxLines: 20,
decoration: InputDecoration(
hintText: '내용을 적어주세요',
border: OutlineInputBorder(),
labelText: "내용을 입력하세요.",
),
),
),
Padding(
padding: EdgeInsets.fromLTRB(20, 5, 20, 5),
child: SizedBox(
height: 50,
width: 400,
child: TextButton(
onPressed: () async {
DataBase dataBase = new DataBase();
var now = DateTime.now();
await dataBase.add(title, content, '$now');
Navigator.pop(context);
},
child: Text(
'글쓰기',
style: TextStyle(color: Colors.black),
),
style: TextButton.styleFrom(primary: Colors.blue),
),
),
),
],
)
],
),
),
);
}
}
''''
this is my code2. this code is to save the data in firestore.
but it does not work.
class DataBase {
FirebaseFirestore firestore = FirebaseFirestore.instance;
String collection = '게시판';
add(String title, String content, String date_time) {
firestore
.collection('카운트')
.doc('카운트')
.get().then((DocumentSnapshot ds) {
firestore.collection(collection).doc('${ds['카운트']!}').set(
{'제목': title, '내용': content,
'날짜': date_time, 'id': ds['카운트']!});
int id = ds['카운트']! + 1;
cntupdate(id);
});
}
void cntupdate(int _id) {
firestore.collection('카운트').doc('카운트').update({'id': _id,
'카운트': _id});
}

How to get multiple urls from firebase storage as array in firestore document?

I have an form (writeUrltoFirestore) which is working except for an array of urls which has to be taken from storage and added to firestore document.
Currently for every file url added in form I have new document at firestore.
So if I select 5 documents and click on "Create" button it will create 5 exactly same documents with only difference their "url" in (writeUrltoFirestore).
As I mentioned it has to create single document in firestore with array of urls for each file stored in storage.
BTW Iam not a programmer - didn't read any book, just always wanted to learn how to make an working app (kinda a dream) so please explain like to a moron if you can and don't get mad if you see something stupid.
Thanks to anyone which is willing to help me.
I need result like this link
Here is code below with some explanations.
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io' show File;
class Fields extends StatefulWidget {
const Fields({Key? key}) : super(key: key);
#override
_FieldsState createState() =>
_FieldsState();
}
class _FieldsState extends State<Fields> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: SingleChildScrollView(child: _Body111()),
);
}
}
class _Body111 extends StatefulWidget {
#override
__Body111State createState() => __Body111State();
}
class __Body111State extends State<_Body111> {
final FirebaseStorage _firebaseStorage = FirebaseStorage.instance;
List<UploadTask> uploadedTasks = [];
List<File> selectedFiles = [];
//-----------------------------------------------------------------------------
// Select files to be uploaded to Storage
Future selectFileTo() async {
try {
FilePickerResult? result = await FilePicker.platform
.pickFiles(allowMultiple: true, type: FileType.any);
if (result != null) {
selectedFiles.clear();
for (var selectedFile in result.files) {
File file = File(selectedFile.path ?? '');
selectedFiles.add(file);
}
} else {
print("User has cancelled the selection");
}
} catch (e) {
print(e);
}
}
//---------------------------------------------------------------------------
// Upload selected files to Storage
uploadFileToStorage(File file) {
UploadTask task = _firebaseStorage
.ref()
.child("files/${DateTime.now().toString()}")
.putFile(file);
return task;
}
//----------------------------------------------------------------------------
// Save files to Storage and get files Urls
saveImageUrlToFirebase(UploadTask task) {
task.snapshotEvents.listen((snapShot) {
if (snapShot.state == TaskState.success) {
snapShot.ref.getDownloadURL().then((urls) =>
writeUrltoFirestore(urls));
}
});
}
//--------------------------------------------------------------------------
// Save files Urls to Firestore document
writeUrltoFirestore(urls) {
Map<String, dynamic> firestoredocData = {
"issue type": selectedValue,
"description": descriptionController.text,
"location": 'Building A',
"category": selectedCategory,
"subcategory": selectedSubcategory,
"uid": firebaseUser!.uid,
//----------------------------------------------------------------------
//----------------------------------------------------------------------
"url": urls, // HERE I HAVE TO STORE ARRAY OF URLS FROM STORAGE
//----------------------------------------------------------------------
//----------------------------------------------------------------------
};
CollectionReference collectionReference =
FirebaseFirestore.instance.collection('issues');
collectionReference.add(firestoredocData);
}
//--------------------------------------------------------------------------
// Button that triggers all
addData() async {
for (var file in selectedFiles) {
final UploadTask task = uploadFileToStorage(file);
saveImageUrlToFirebase(task);
setState(() {
uploadedTasks.add(task);
});
}
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('created successfully')));
Navigator.pop(context);
}
//----------------------------------------------------------------------------
// Other fields from Map above
List<String> categories = ['111', '222', '333'];
List<String> generalSubcategory = ['1111111', '2222222', '333333333'];
List<String> cleaningSubcategory = [
'1',
'2',
'3'
];
List<String> othersSubcategory = ['01', '02', '03'];
List<String> subcategory = [];
String? selectedCategory;
String? selectedSubcategory;
final TextEditingController descriptionController = TextEditingController();
var firebaseUser = FirebaseAuth.instance.currentUser;
String? selectedValue;
List<String> arrayList = [
'Individual ',
'Maintenance '
];
Widget _description() {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 35, 0, 0),
child: TextFormField(
controller: descriptionController,
decoration: InputDecoration(
hintText: 'Here you can describe ...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(20.0),
borderSide: const BorderSide(color: Colors.grey),
),
),
maxLines: 8,
),
);
}
#override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) =>
Stack(
children: [
GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
},
child: SingleChildScrollView(
child: Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0),
child: _description(),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0),
child: Container(
padding: const EdgeInsets.fromLTRB(13, 0, 25, 0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset:
Offset(5, 5), // changes position of shadow
),
],
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
dropdownColor: Colors.white,
borderRadius: BorderRadius.circular(20),
hint: const Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(
'Categories',
style: TextStyle(),
)),
value: selectedCategory,
isExpanded: true,
items: categories.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Padding(
padding:
const EdgeInsets.fromLTRB(25, 0, 0, 0),
child: Text(
value,
textAlign: TextAlign.center,
style: const TextStyle(),
),
),
);
}).toList(),
onChanged: (category) {
if (category == '222') {
subcategory = cleaningSubcategory;
} else if (category == '111') {
subcategory = generalSubcategory;
} else if (category == '333') {
subcategory = othersSubcategory;
} else {
subcategory = [];
}
setState(() {
selectedSubcategory = null;
selectedCategory = category;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 0, 25, 0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset:
Offset(5, 5), // changes position of shadow
),
],
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
dropdownColor: Colors.white,
borderRadius: BorderRadius.circular(20),
hint: const Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(
'Subcategories',
style: TextStyle(),
)),
value: selectedSubcategory,
isExpanded: true,
items: subcategory.map((String value) {
return DropdownMenuItem<String>(
value: value,
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(value),
),
);
}).toList(),
onChanged: (subcategory) {
setState(() {
selectedSubcategory = subcategory;
});
},
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0),
child: Container(
padding: const EdgeInsets.fromLTRB(20, 0, 25, 0),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: const [
BoxShadow(
color: Colors.grey,
spreadRadius: 2,
blurRadius: 2,
offset:
Offset(5, 5), // changes position of shadow
),
],
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius:
const BorderRadius.all(Radius.circular(20)),
),
child: DropdownButtonHideUnderline(
child: DropdownButtonFormField<String>(
dropdownColor: Colors.white,
decoration: const InputDecoration(
enabledBorder: InputBorder.none,
),
validator: (value) =>
selectedValue == null
? 'Please select type'
: null,
hint: const Padding(
padding: EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(
'Type',
),
),
value: selectedValue,
isExpanded: true,
icon: const Icon(Icons.arrow_drop_down),
items: arrayList.map((String string) {
return DropdownMenuItem<String>(
value: string,
child: Padding(
padding:
const EdgeInsets.fromLTRB(10, 0, 0, 0),
child: Text(string),
),
);
}).toList(),
onChanged: (String? string) {
setState(() {
selectedValue = string;
});
},
),
),
),
),
const Padding(
padding: EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0)),
IconButton(
onPressed: selectFileTo,
icon: const Icon(
Icons.camera_alt_outlined,
size: 30,
color: Colors.grey,
)),
const Padding(
padding: EdgeInsets.only(
left: 20.0, right: 20.0, top: 20.0)),
Padding(
padding: const EdgeInsets.only(
left: 30.0, right: 30.0, top: 5.0),
child: ElevatedButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(
const EdgeInsets.all(0)),
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0),
)),
backgroundColor: MaterialStateProperty.all<
Color>(
Colors.transparent),
shadowColor: MaterialStateProperty.all<Color>(
Colors.transparent)),
onPressed: addData,
child: Container(
decoration: const BoxDecoration(
borderRadius:
BorderRadius.all(Radius.circular(20)),
),
constraints: const BoxConstraints(
minWidth: 120, minHeight: 40),
alignment: Alignment.center,
child: const Center(
child: Text(
"Create",
textAlign: TextAlign.center,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
),
),
],
),
),
),
),
],
),
);
}
}
// End of dart file
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Firebase API (separate dart file)
import 'dart:io';
import 'dart:typed_data';
import 'package:firebase_storage/firebase_storage.dart';
class FirebaseApi {
static UploadTask? uploadFile(String destination, File file) {
try {
final ref = FirebaseStorage.instance.ref(destination);
return ref.putFile(file);
} on FirebaseException catch (e) {
return null;
}
}
static UploadTask? uploadBytes(String destination, Uint8List data) {
try {
final ref = FirebaseStorage.instance.ref(destination);
return ref.putData(data);
} on FirebaseException catch (e) {
return null;
}
}
}
//-----------------------------------------------------------------------------
You should call writeUrltoFirestore at last of all upload. Maintain an List at top.
List<String> _urls = [];
in saveImageUrlToFirebase
saveImageUrlToFirebase(UploadTask task) {
task.snapshotEvents.listen((snapShot) {
if (snapShot.state == TaskState.success) {
snapShot.ref.getDownloadURL().then((url) =>
_urls.add(url.toString()));
}
});
}
In final upload task simply call
writeUrltoFirestore(_urls);

Why is data not showing on first click? flutter

Why is data not showing on first click?
this is a problem i ran into later. Previously, the data was coming when I first clicked or when the program was first opened, but then I guess I broke a code without realizing it and I can't fix it back please help me
widget's code
import 'package:flutter/material.dart';
import 'package:todo/data/todo_service.dart';
import 'package:todo/models/todo.dart';
class TodoListWidget extends StatefulWidget{
#override
State<StatefulWidget> createState() {
return TodoListWidgetState();
}
}
class TodoListWidgetState extends State<TodoListWidget>{
TodoService todoService = TodoService.instance;
List<Todo> todoList = [];
#override
Widget build(BuildContext context) {
return getTodoList(todoList);
}
#override
void initState() {
setState(() {
loadData();
});
super.initState();
}
getTodoList(List<Todo> todos) {
return todoList.isEmpty ? Center(child: Text("Nothing to do yet...", style: TextStyle(color: Colors.black, fontWeight: FontWeight.bold),)) :
ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return Card(
color: const Color(0xffFE7E6D),
child: Padding(
padding: const EdgeInsets.all(15),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
todos[index].title!,
style: TextStyle(
fontSize: 20, color: Colors.white),
),
Row(
children: [
Checkbox( value: todos[index].isDone,onChanged:(value){
setState(() {
todos[index].isDone = value;
});
},
),
IconButton(onPressed: (){
setState(() {
if(todos[index].isFavourite!){
todos[index].isFavourite = false;
}
else{
todos[index].isFavourite = true;
}
});
},
icon: todos[index].isFavourite! ? Icon(Icons.favorite) : Icon(Icons.favorite_border)),
IconButton(onPressed: (){
setState(() {
todoService.deleteTodo(todos[index]);
loadData();
});
},
icon: Icon(Icons.delete_outline)),
],
)
],
),
const SizedBox(
height: 10,
),
Container(
child: Text(
todos[index].description!,
style: TextStyle(
letterSpacing: 1, color: Colors.white),
),
color: Colors.transparent,
width: MediaQuery.of(context).size.width,
),
],
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),);
},
);
}
void loadData() {
setState(() {
todoService.getTodos(false).then((value) {
todoList = value;
});
});
}
}
Main screen
import 'package:flutter/material.dart';
import 'package:flutter_advanced_drawer/flutter_advanced_drawer.dart';
import 'package:todo/screens/add_todo_screen.dart';
import 'package:todo/widgets/favourites_widget.dart';
import 'package:todo/widgets/todo_list_widget.dart';
import 'package:todo/widgets/todo_widget.dart';
class MainScreen extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MainScreenState();
}
}
class MainScreenState extends State {
final _advancedDrawerController = AdvancedDrawerController();
Widget? widgetForBody;
bool? _floatButton = true;
#override
void initState() {
setState(() {
widgetForBody = TodoListWidget();
});
super.initState();
}
#override
Widget build(BuildContext context) {
return AdvancedDrawer(
backdropColor: Colors.grey.shade900,
controller: _advancedDrawerController,
animationCurve: Curves.easeInOut,
animationDuration: const Duration(milliseconds: 300),
animateChildDecoration: true,
rtlOpening: false,
disabledGestures: false,
childDecoration: const BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(30)),
),
child: Scaffold(
appBar: AppBar(
backgroundColor: Colors.grey.shade900,
shadowColor: Colors.transparent,
title: const Text('My To Do',
style: TextStyle(
color: Colors.white54,
fontSize: 25,
fontWeight: FontWeight.bold)),
centerTitle: true,
leading: IconButton(
color: Colors.white54,
onPressed: _handleMenuButtonPressed,
icon: ValueListenableBuilder<AdvancedDrawerValue>(
valueListenable: _advancedDrawerController,
builder: (_, value, __) {
return AnimatedSwitcher(
duration: Duration(milliseconds: 250),
child: Icon(
value.visible ? Icons.clear : Icons.apps,
key: ValueKey<bool>(value.visible),
),
);
},
),
),
),
body: widgetForBody,
floatingActionButton: _floatButton!
? FloatingActionButton(
onPressed: () {
setState(() {
widgetForBody = null;
});
goToTodoAdd();
},
child: Icon(
Icons.add,
color: Colors.white54,
),
backgroundColor: Colors.grey.shade900,
)
: null,
),
drawer: SafeArea(
child: Container(
child: ListTileTheme(
textColor: Colors.white,
iconColor: Colors.white,
child: Column(
mainAxisSize: MainAxisSize.max,
children: [
SizedBox(
height: 150,
),
Text(
"WELCOME BACK",
style: TextStyle(color: Colors.white54, fontSize: 20),
),
SizedBox(
height: 50,
),
ListTile(
onTap: () {
setState(() {
widgetForBody = TodoListWidget();
_advancedDrawerController.value =
AdvancedDrawerValue.hidden();
_floatButton = true;
});
},
leading: Icon(Icons.check_box_outline_blank_sharp),
title: Text('To Do List',
style: TextStyle(color: Colors.white54)),
),
ListTile(
onTap: () {
setState(() {
widgetForBody = TodoWidget();
_advancedDrawerController.value =
AdvancedDrawerValue.hidden();
_floatButton = false;
});
},
leading: Icon(Icons.check_box_outlined),
title:
Text('History', style: TextStyle(color: Colors.white54)),
),
ListTile(
onTap: () {
setState(() {
widgetForBody = FavouritesWidget();
_advancedDrawerController.value =
AdvancedDrawerValue.hidden();
_floatButton = false;
});
},
leading: Icon(Icons.favorite),
title: Text('Favourites',
style: TextStyle(color: Colors.white54)),
),
Divider(indent: 20, height: 20, color: Colors.grey.shade800),
ListTile(
onTap: () {
setState(() {});
},
leading: Icon(Icons.info_outline),
title: Text('Info', style: TextStyle(color: Colors.white54)),
),
Spacer(),
DefaultTextStyle(
style: TextStyle(
fontSize: 12,
color: Colors.white54,
),
child: Container(
margin: const EdgeInsets.symmetric(
vertical: 16.0,
),
child: Text('To Do App Demo'),
),
),
],
),
),
),
),
);
}
void _handleMenuButtonPressed() {
// NOTICE: Manage Advanced Drawer state through the Controller.
_advancedDrawerController.showDrawer();
}
void goToTodoAdd() async {
bool result = await Navigator.push(
context, MaterialPageRoute(builder: (context) => AddTodoScreen()));
if (result != null) {
if (result) {
setState(() {
getTodoWidget();
});
}
}
}
getTodoWidget() {
setState(() {
widgetForBody = TodoListWidget();
});
}
}
and service
import 'dart:async';
import 'package:path/path.dart';
import 'package:sqflite/sqflite.dart';
import 'package:todo/models/todo.dart';
class TodoService{
static TodoService instance = TodoService._internal();
TodoService._internal();
Database? _db;
factory TodoService(){
return instance;
}
Future<Database?> get db async{
if(_db == null){
_db = await _initDb();
}
return _db;
}
Future<Database> _initDb() async{
String dbPath = join(await getDatabasesPath(), "todo.db");
final todoDb = openDatabase(dbPath, version: 1, onCreate: createDb);
return todoDb;
}
void createDb(Database db, int version) async {
await db.execute("CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, description TEXT, isDone INT, isFavourite INT)");
}
Future<int> addTodo(Todo todo) async{
Database? db = await this.db;
var result = await db!.insert("todos", todo.toMap());
print(result);
return result;
}
Future<int> updateTodo(Todo todo) async{
Database? db = await this.db;
var result = await db!.update("todos", todo.toMap(), where: "id=?", whereArgs: [todo.id]);
return result;
}
Future<int> deleteTodo(Todo todo) async{
Database? db = await this.db;
var result = await db!.delete("todos",where: "id=?", whereArgs: [todo.id]);
return result;
}
Future<List<Map<String,dynamic>>?> getTodoMaps()async{
Database? db = await this.db;
return await db!.query("todos");
}
Future<List<Todo>> getTodos(bool isDone)async{
final mapList = await getTodoMaps();
List<Todo> todoList = [];
mapList?.forEach((element) {
todoList.add(Todo.fromMap(element));
});
if(isDone){
return todoList.where((element) => element.isDone == true).toList();
}
return todoList.where((element) => element.isDone == false).toList();
}
Future<List<Todo>> getFavouritesTodos()async{
final mapList = await getTodoMaps();
List<Todo> todoList = [];
mapList?.forEach((element) {
todoList.add(Todo.fromMap(element));
});
return todoList.where((element) => element.isFavourite == true).toList();
}
}
thank you
put the setstate inside the then
after you have received the result the screen will be updated
void loadData() {
todoService.getTodos(false).then((value) {
setState(() {
todoList = value;
});
});
}

Resources