I keep getting this error when trying to post data and the solutions say to check if(mounted) before calling setState but I don't know where this setState is? The code is below; the function is in the first widget and then I call it in another widget:
// ignore_for_file: use_build_context_synchronously
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:mne/Forms/form_model.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../Network/api.dart';
class FormWidget extends StatefulWidget {
const FormWidget({Key? key}) : super(key: key);
@override
State<FormWidget> createState() => FormWidgetState();
}
class FormWidgetState extends State<FormWidget> {
// to show error message
_showScaffold(String message) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text(message, style: const TextStyle(color: Colors.black)),
duration: const Duration(seconds: 20),
action: SnackBarAction(
textColor: Colors.white,
label: 'Press to go back',
onPressed: () {
Navigator.of(context).pop();
},
),
backgroundColor: Colors.redAccent));
}
final List<FormModel> _formfields = [];
var loading = false;
var isEmpty = false;
List activityResponses = [];
late Map<String, List<dynamic>> data;
// to fetch form fields
fetchFormFields() async {
setState(() {
loading = true;
});
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences localStorage = await SharedPreferences.getInstance();
var saved = localStorage.getString('activitytask_id');
var res = await Network().getData('mobile/activity-fields/$saved');
if (res.statusCode == 200) {
final data = jsonDecode(res.body);
final tdata = data['data'];
if (tdata.length == 0) {
Navigator.of(context).pushReplacementNamed('error');
}
var formfieldsJson = tdata;
setState(() {
for (Map formfieldJson in formfieldsJson) {
_formfields.add(FormModel.fromJson(formfieldJson));
}
loading = false;
});
}
}
final TextEditingController _textController = TextEditingController();
final TextEditingController _numberController2 = TextEditingController();
@override
void initState() {
super.initState();
fetchFormFields();
}
submitResult() async {
WidgetsFlutterBinding.ensureInitialized();
SharedPreferences localStorage = await SharedPreferences.getInstance();
final String? responseData = localStorage.getString('responses');
final String responseList = json.decode(responseData!);
final List responseList2 = [responseList];
debugPrint(responseList.toString());
data = {"activity_responses": responseList2};
var res = await Network().authData(data, 'mobile/activity-result');
if (res.statusCode == 200) {
Navigator.of(context).pushReplacementNamed('activitytasks');
} else {
Navigator.of(context).pushReplacementNamed('error');
}
}
@override
void dispose() {
_textController.dispose();
_numberController2.dispose();
super.dispose();
}
// to display form fields
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.white,
child: loading
? const Center(child: CircularProgressIndicator())
: ListView.builder(
itemCount: _formfields.length,
itemBuilder: (context, i) {
final nDataList = _formfields[i];
return Form(
child: Column(children: [
Column(children: [
if (nDataList.type == 'text')
Column(children: [
Container(
alignment: Alignment.centerLeft,
padding:
const EdgeInsets.only(bottom: 5, left: 6),
child: Text('Add a ${nDataList.name}',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold)),
),
Container(
margin: const EdgeInsets.all(8),
child: TextFormField(
controller: _textController,
decoration: InputDecoration(
contentPadding:
const EdgeInsets.all(15),
border: const OutlineInputBorder(),
filled: true,
fillColor: Colors.grey[200],
labelText: nDataList.name),
)),
Container(
alignment: Alignment.centerRight,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.green)),
onPressed: () async {
var responseData = {
"activity_field_id": nDataList.id,
"value": _textController.text
};
activityResponses.add(responseData);
debugPrint(activityResponses.toString());
},
child: const Text('Save',
style: TextStyle(color: Colors.white)),
),
),
]),
if (nDataList.type == 'number')
Column(children: [
Container(
alignment: Alignment.centerLeft,
padding: const EdgeInsets.only(
bottom: 5, left: 6, top: 5),
child: Text('Add a ${nDataList.name}',
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold)),
),
Container(
margin: const EdgeInsets.all(8),
child: TextFormField(
controller: _numberController2,
decoration: InputDecoration(
contentPadding:
const EdgeInsets.all(15),
border: const OutlineInputBorder(),
filled: true,
fillColor: Colors.grey[200],
labelText: nDataList.name),
)),
Container(
alignment: Alignment.centerRight,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.green)),
onPressed: () async {
// valueResponses.add(_numberController2.text);
// idResponses.add(nDataList.id);
var numberData = {
"activity_field_id": nDataList.id,
"value": _numberController2.text
};
activityResponses.add(numberData);
debugPrint(activityResponses.toString());
SharedPreferences localStorage =
await SharedPreferences.getInstance();
final String encodedData =
(activityResponses).asMap().toString();
final String encodedData2 =
jsonEncode(encodedData);
localStorage.setString(
'responses', encodedData2);
},
child: const Text('Save',
style: TextStyle(color: Colors.white)),
),
),
]),
]),
]));
})));
}
}
The above code is the first widget where I have written submitResult() . The code below is for the page containing the button that will call submitResult() :
import 'package:flutter/material.dart';
import '../Design/custom_shape.dart';
import 'form_widget.dart';
class Workspace extends StatefulWidget {
const Workspace({Key? key}) : super(key: key);
@override
State<Workspace> createState() => WorkspaceState();
}
class WorkspaceState extends State<Workspace> {
bool isLoading = true;
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
backgroundColor: const Color.fromARGB(255, 236, 246, 219),
body: Column(
children: [
Container(
alignment: Alignment.center,
child: Stack(clipBehavior: Clip.none, children: [
ClipPath(
clipper: CustomShape(),
child: Container(
padding: const EdgeInsets.only(bottom: 128),
height: 335,
child: Image.asset('assets/images/fields.png',
fit: BoxFit.fitWidth))),
Container(
height: 650,
width: double.infinity,
color: Colors.transparent,
),
Positioned(
top: 140,
right: 8,
height: 600,
child: Container(
alignment: Alignment.center,
width: 360,
margin: const EdgeInsets.all(5),
padding: const EdgeInsets.all(5),
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.all(Radius.circular(10))),
child: Column(
children: [
Container(
height: 450,
width: double.infinity,
child: const FormWidget()),
if (isLoading)
Container(
alignment: Alignment.bottomCenter,
child: ElevatedButton(
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all<Color>(
Colors.green)),
onPressed: () async {
setState(() {
isLoading = false;
});
await FormWidgetState().submitResult();
if (!mounted) return;
setState(() {
isLoading = true;
});
// Navigator.of(context).pop();
},
child: const Text('Submit',
style: TextStyle(color: Colors.white)),
),
)
else
const Center(
child: CircularProgressIndicator(
backgroundColor:
Color.fromRGBO(0, 161, 39, 1)))
],
)),
),
])),
],
),
);
}
}
Any help is appreciated thank you
Edit: Adding this image after removing the
// ignore_for_file: use_build_context_synchronously
