how to refresh page after send POST API in flutter - flutter

I have a POST API that when I send a request, I give the GET API request on the same screen to show the json data.
When I send information, after sending the information, the Get data is not displayed and must be logged out to display GET API data.
How can I refresh the page after sending the POST API data, so that the information is displayed after sending
POST API:
void ladderAsli() async {
if (_avgWeeklySales.text.isNotEmpty) {
print(token);
var response = await http.post(
Uri.parse("localhost/backend/api/v1/pellekan/main/add/"),
body: ({
"avgWeeklySales": _avgWeeklySales.text,
}),
headers: {
'Authorization': 'Bearer $token',
});
var body = jsonDecode(response.body);
if (response.statusCode == 200) {
SharedPreferences pref = await SharedPreferences.getInstance();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['success']}')));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['error']}')));
}
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('error')));
}
}
and GET API:
Future getDataLadder() async {
print('bye');
String token = await getToken();
var response = await http.get(
Uri.parse('localhost/backend/api/v1/pellekan/main/active'),
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print('Response Body : ${response.body}');
if (response.statusCode == 400) {
var chieIN = jsonDecode(response.body);
print("be moshkel khordim hich dataei nist");
}
if (response.statusCode == 200) {
var chieIN = jsonDecode(response.body);
// print('Hosssssein ' +
// chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
val = chieIN['pellekanInfo']['pellekanPublishStatus'].toString();
print('BODOBA : ${val}');
setState(() {
val = '0';
});
//setState(() {
// stringResponse = jsonDecode(response.body)['pellekan'];
// val!.add(chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
stringResponse = [];
stringResponse.addAll(List<NardebanData>.from(json
.decode(response.body)['pellekan']
.map((x) => NardebanData.fromJson(x))));
print('String Response : ${stringResponse}');
// nardeban_data = (stringResponse as List<NardebanData>).map((d) => NardebanData.fromJson(d)).toList();
//});
} else {
print("error");
}
}
in the initState call getDataLadder()
Refreshpage
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:project/pattern_formatter.dart';
import 'package:project/screens/result-ladder.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
List<NardebanData> nardeban_data = [];
List<NardebanData> stringResponse = [];
class Ladder extends StatefulWidget {
const Ladder({Key? key}) : super(key: key);
#override
_LadderState createState() => _LadderState();
}
Future<String> getToken() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString('login')!;
}
class _LadderState extends State<Ladder> {
bool value = true;
String? val = "";
String token = "";
#override
void initState() {
super.initState();
getDataLadder();
getInfo();
}
void getInfo() async {
SharedPreferences pref = await SharedPreferences.getInstance();
setState(() {
token = pref.getString("login")!;
});
}
TextEditingController _avgWeeklySales = TextEditingController();
TextEditingController _doubleSellingPricePercent = TextEditingController();
TextEditingController _tripleSellingPricePercent = TextEditingController();
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Directionality(
textDirection: TextDirection.rtl, child: gochgochApp()));
}
Future getDataLadder() async {
print('bye');
String token = await getToken();
var response = await http.get(
Uri.parse('localhost/backend/api/v1/pellekan/main/active'),
headers: {
'Content-type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer $token',
});
print('Token : ${token}');
print('Response Body : ${response.body}');
if (response.statusCode == 400) {
var chieIN = jsonDecode(response.body);
print("be moshkel khordim hich dataei nist");
}
if (response.statusCode == 200) {
var chieIN = jsonDecode(response.body);
// print('Hosssssein ' +
// chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
val = chieIN['pellekanInfo']['pellekanPublishStatus'].toString();
print('BODOBA : ${val}');
setState(() {
val = '0';
});
//setState(() {
// stringResponse = jsonDecode(response.body)['pellekan'];
// val!.add(chieIN['pellekanInfo']['pellekanPublishStatus'].toString());
stringResponse = [];
stringResponse.addAll(List<NardebanData>.from(json
.decode(response.body)['pellekan']
.map((x) => NardebanData.fromJson(x))));
print('String Response : ${stringResponse}');
// nardeban_data = (stringResponse as List<NardebanData>).map((d) => NardebanData.fromJson(d)).toList();
//});
} else {
print("hooooooooooooooooooooooooo");
}
}
// Future asyncokeyeData() async {
// SharedPreferences pref = await SharedPreferences.getInstance();
// val = pref.getString('okeyeData');
// }
Widget gochgochApp() {
print('Valiable : ${val}');
if (val == '0') {
print(val);
// return Container(
// height: 200.0,
// child: Center(child: Text('شما در انتظار تایید نیست')),
// );
// return alertInForProcessLadder();
return getBody();
// return getBody();
}
// if (val == '2' || val == null) {
// return getForm();
// }
else {
return getForm();
}
}
Widget alertInForProcessLadder() {
return (SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 24),
child: SingleChildScrollView(
child: Container(
child: Center(
child: Text(
'شما یک پلکان اصلی در انتظار تایید ادمین دارید و نمی توانید پلکان دیگری ایجاد کنید')),
height: 200.0,
),
)),
));
}
Widget getForm() {
return (SafeArea(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 24),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 9,
),
Text(
"فرم نردبان اصلی",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18,
color: Colors.blue,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 10,
),
Container(
padding: EdgeInsets.all(28),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
),
child: Column(
children: [
Text(
'مبلغ را به تومان وارد کنید',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 4,
),
TextField(
controller: _avgWeeklySales,
textAlign: TextAlign.center,
cursorColor: Colors.blue,
keyboardType: TextInputType.number,
inputFormatters: [ThousandsFormatter()],
decoration: InputDecoration(
hintStyle:
TextStyle(color: Colors.black26, fontSize: 13),
hintText: 'مثال : 1,000,000',
border: OutlineInputBorder(),
hintTextDirection: TextDirection.rtl,
contentPadding: EdgeInsets.all(8),
),
),
SizedBox(
height: 22,
),
Text(
'درصد تخفیف برای 20 عدد',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 4,
),
TextField(
controller: _doubleSellingPricePercent,
textAlign: TextAlign.center,
cursorColor: Colors.blue,
keyboardType: TextInputType.number,
inputFormatters: [ThousandsFormatter()],
decoration: InputDecoration(
hintStyle:
TextStyle(color: Colors.black26, fontSize: 13),
hintText: 'مثال : 20',
border: OutlineInputBorder(),
hintTextDirection: TextDirection.rtl,
contentPadding: EdgeInsets.all(8),
),
),
SizedBox(
height: 22,
),
Text(
'درصد تخفیف برای 30 عدد',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.black54,
fontWeight: FontWeight.bold,
),
),
SizedBox(
height: 4,
),
TextField(
controller: _tripleSellingPricePercent,
textAlign: TextAlign.center,
cursorColor: Colors.blue,
keyboardType: TextInputType.number,
inputFormatters: [ThousandsFormatter()],
decoration: InputDecoration(
hintStyle:
TextStyle(color: Colors.black26, fontSize: 13),
hintText: 'مثال : 30',
border: OutlineInputBorder(),
hintTextDirection: TextDirection.rtl,
contentPadding: EdgeInsets.all(8),
),
),
SizedBox(
height: 25,
),
SizedBox(
width: double.infinity,
child: ElevatedButton(
onPressed: () {
ladderAsli();
},
style: ButtonStyle(
shape: MaterialStateProperty.all<
RoundedRectangleBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.0),
),
),
foregroundColor:
MaterialStateProperty.all<Color>(Colors.white),
backgroundColor:
MaterialStateProperty.all<Color>(Colors.blue),
),
child: Padding(
child: Text(
'تایید',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 21),
),
padding: EdgeInsets.all(15.0),
),
),
),
],
),
),
],
),
)),
));
}
Widget getBody() {
var size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: size.height,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(10),
bottomRight: Radius.circular(10)),
color: Colors.white),
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 10,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
child: Container(
height: 1,
decoration:
BoxDecoration(color: Colors.grey.withOpacity(0.2)),
),
),
SizedBox(
width: 10,
),
buildHeader(
text: 'جهت فعال سازی پله 30 عددی فیلد زیر را فعال کنید',
child: buildSwitch(),
),
SizedBox(
width: 10,
),
Flexible(
child: Container(
height: 1,
decoration:
BoxDecoration(color: Colors.grey.withOpacity(0.2)),
),
),
],
),
SizedBox(
height: 15,
),
Column(
children: List.generate(stringResponse.length, (index) {
NardebanData dataItem = stringResponse[index];
return Column(
children: [
Padding(
padding: const EdgeInsets.only(right: 5, left: 5),
child: Container(
decoration: new BoxDecoration(
image: new DecorationImage(
image: new AssetImage("assets/images/bg.png"),
fit: BoxFit.fill,
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
height: 90,
// width: (size.width - 20) * 0.68,
child: Row(
children: [
SizedBox(width: 20), // give it width
Container(
width: 60,
decoration: BoxDecoration(
color: Colors.blue,
border:
Border.all(color: Colors.blue),
borderRadius:
BorderRadius.circular(40.0)),
child: Padding(
padding: EdgeInsets.all(10.0),
child: Text(dataItem.name!,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.5,
fontWeight: FontWeight.bold,
color: Colors.white)))),
SizedBox(
width: 10,
),
Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
dataItem.form ?? '' + '',
style: TextStyle(
fontSize: 14,
color: Colors.black54,
fontWeight: FontWeight.w400),
overflow: TextOverflow.ellipsis,
),
],
),
),
Container(
child: Column(
mainAxisAlignment:
MainAxisAlignment.center,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
' تا ' + dataItem.to!,
style: TextStyle(
fontSize: 14,
color: Colors.black54,
fontWeight: FontWeight.w400),
overflow: TextOverflow.ellipsis,
),
],
),
)
],
),
),
Container(
width: (size.width - 120) * 0.32,
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
border: Border.all(color: Colors.blue)),
child: Padding(
padding: const EdgeInsets.only(
right: 10,
bottom: 4,
left: 10,
top: 4),
child: Row(
children: [
SizedBox(
width: 25,
height: 25,
child: TextField(
textAlign: TextAlign.center,
keyboardType:
TextInputType.number,
decoration: InputDecoration(
hintText: dataItem.percent!,
border: InputBorder.none,
contentPadding: EdgeInsets.only(
bottom: 8,
top: 3,
),
),
),
)
],
),
),
),
// Icon(
// Icons.notifications,
// size: 22,
// color: Colors.blue.withOpacity(0.7),
// )
],
),
)
],
),
)),
],
);
})),
],
),
),
);
}
Widget buildHeader({
required Widget child,
required String text,
}) =>
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
text,
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
),
const SizedBox(height: 3),
child,
],
);
Widget buildSwitch() => Transform.scale(
scale: 2,
child: Switch.adaptive(
activeColor: Colors.blueAccent,
activeTrackColor: Colors.blue.withOpacity(0.4),
// inactiveThumbColor: Colors.orange,
// inactiveTrackColor: Colors.black87,
splashRadius: 50,
value: value,
onChanged: (value) => setState(() => this.value = value),
),
);
void ladderAsli() async {
if (_avgWeeklySales.text.isNotEmpty) {
print(token);
var response = await http.post(
Uri.parse("localhost/backend/api/v1/pellekan/main/add/"),
body: ({
"avgWeeklySales": _avgWeeklySales.text,
"doubleSellingPricePercent": _doubleSellingPricePercent.text,
"tripleSellingPricePercent": _tripleSellingPricePercent.text,
}),
headers: {
'Authorization': 'Bearer $token',
});
var body = jsonDecode(response.body);
if (response.statusCode == 200) {
SharedPreferences pref = await SharedPreferences.getInstance();
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['success']}')));
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('${body['error']}')));
}
} else {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text('مبلغ کل را وارد کنید')));
}
}
}
this is json sample:
{
"pellekan": [
{
"name": "پله 1",
"form": null,
"to": "9999",
"percent": 1
},
{
"name": "پله 2",
"form": "9999",
"to": 10.74,
"percent": 2.89
},
{
]
}

Listview.builder widget used to propagate the change in ui
ListView.builder(
itemCount: datajson!.length,
itemBuilder: (context, index) {
return Text(datajson![index].toString(),
style: TextStyle(fontSize: 10));
})
Here i use sample post and getmethod with future delay like mimic the api wait and supply the data.
void MygetData() {
Future.delayed(Duration(seconds: 3), () {
setState(() {
isloading = false;
datajson;
});
});
}
void posts() {
Future.delayed(Duration(seconds: 3), () {
// other post request
datajson?.add({"name": "2"});
MygetData();
});
}
SampleCode dartpad live
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
int myvalue = 0;
List<Map<String, dynamic>>? datajson = [];
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
bool isloading = false;
#override
void initState() {
isloading = true;
Future.delayed(Duration(seconds: 3), () {
setState(() {
datajson?.add({"name": "1"});
isloading = false;
});
});
}
void MygetData() {
Future.delayed(Duration(seconds: 3), () {
setState(() {
isloading = false;
datajson;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
// shrinkWrap: true,
children: [
Container(
height: 45,
child: ElevatedButton(
onPressed: () {
setState(() {
isloading = true;
});
posts();
},
child: Text(
"Post",
style: TextStyle(fontSize: 10),
)),
),
Expanded(
child: ListView.builder(
itemCount: datajson!.length,
itemBuilder: (context, index) {
return Text(datajson![index].toString(),
style: TextStyle(fontSize: 10));
}),
),
isloading
? Container(
height: 50,
width: 50,
child: CircularProgressIndicator(),
)
: Text("")
],
),
);
}
void posts() {
Future.delayed(Duration(seconds: 3), () {
// other post request
datajson?.add({"name": "2"});
MygetData();
});
}
}

i think best and easy way to solve this problem.
Navigator.push(context,MaterialPageRoute(builder: (context) =>yourclass()));
but you should fetch data in initstate like this.
void initState() { fetchYourItems(); super.initState(); };

Related

Flutter - ScrollController was used after being disposed

class HomeScreen extends StatefulWidget {
final userName;
HomeScreen(this.userName);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
Future<ClientDashboardModel?>? _meterReadingResponse;
BatchSummaryModel? _batchResponse;
AMRDashboardModel? _amrDashboardResponse;
String _userName = '';
int? qcAssignedReads = 0;
int? qcMrCompleted = 0;
int? qcCompletedReads = 0;
int? qcPendingReads = 0;
int? qcApprovedReads = 0;
int? qcRejectedReads = 0;
bool isFirstTimeCalled = false;
Timer? _timer;
int _currentIndex = 0;
final pages = [
const MDMScreen(),
const AMRDashboard(whichScreen: 0),
const AMRDashboard(whichScreen: 1),
const AMRDashboard(whichScreen: 2)
];
class _HomeScreenState extends State<HomeScreen> {
#override
void initState() {
setUpTimedFetch();
super.initState();
if (widget.userName != null) _userName = (widget.userName!);
}
#override
void dispose() {
isFirstTimeCalled = false;
_timer?.cancel();
super.dispose();
}
void setUpTimedFetch() {
if (!isFirstTimeCalled) {
_meterReadingResponse = _getDashboardData();
}
isFirstTimeCalled = true;
}
Future<ClientDashboardModel?> _getDashboardData() async {
ClientDashboardModel? meterReadingResponse;
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('token')!;
var responseData = await Dashboard().getClientDashboard(token);
if (responseData.statusCode == 200) {
String data = responseData.body;
var decodedData = jsonDecode(data);
meterReadingResponse = null;
meterReadingResponse = ClientDashboardModel.fromJson(decodedData);
return meterReadingResponse;
}
return null;
}
void logout() async {
SharedPreferences.getInstance().then((value) {
value.remove('token');
value.remove('userName');
});
Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) {
return const LoginScreen();
}));
}
Future<void> _showMyDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: const Text(Strings.kLogoutLabel),
content: const Text(Strings.kConfirmLogout),
actions: <Widget>[
TextButton(
child: const Text(Strings.kCancelLabel),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: const Text(Strings.kOKLabel),
onPressed: () {
Navigator.of(context).pop();
logout();
},
)
],
);
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _currentIndex,
backgroundColor: const Color(0XFF116AFF),
unselectedItemColor: Colors.white,
selectedLabelStyle: const TextStyle(color: Colors.white),
showUnselectedLabels: false,
onTap: (value) {
setState(() => _currentIndex = value);
},
items: [
BottomNavigationBarItem(
label: 'MDM',
icon: Container(
decoration: BoxDecoration(
color:
_currentIndex == 0 ? Colors.white : Colors.transparent,
shape: BoxShape.circle),
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Icon(Icons.electric_meter_outlined),
),
),
),
BottomNavigationBarItem(
label: 'Site Survey',
icon: Container(
decoration: BoxDecoration(
color:
_currentIndex == 1 ? Colors.white : Colors.transparent,
shape: BoxShape.circle),
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Icon(Icons.location_city_outlined),
),
),
),
BottomNavigationBarItem(
label: 'Meter Replace',
icon: Container(
decoration: BoxDecoration(
color:
_currentIndex == 2 ? Colors.white : Colors.transparent,
shape: BoxShape.circle),
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Icon(Icons.library_books_outlined),
),
),
),
BottomNavigationBarItem(
label: 'TroubleShoot',
icon: Container(
decoration: BoxDecoration(
color:
_currentIndex == 3 ? Colors.white : Colors.transparent,
shape: BoxShape.circle),
child: const Padding(
padding: EdgeInsets.all(10.0),
child: Icon(Icons.info_outline),
),
),
),
],
),
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text(Strings.kMRDLabel),
actions: [
IconButton(
onPressed: () {
_showMyDialog();
},
icon: const Icon(Icons.power_settings_new))
],
),
body: childView());
}
Widget childView() {
return SingleChildScrollView(
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
Strings.kWelcome2Label,
style: TextStyle(
color: Colors.amber.shade700,
fontSize: 16.0,
fontWeight: FontWeight.w600),
),
Text(
_userName.toTitleCase(),
style: const TextStyle(
color: Colors.black,
fontSize: 16.0,
fontWeight: FontWeight.w400),
)
],
),
const Spacer(),
ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(color: Colors.grey.shade200),
child: SvgPicture.asset(
'images/profile.svg',
height: 54.0,
width: 54.0,
),
),
),
],
),
const SizedBox(
height: 30,
),
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [pages[_currentIndex]],
),
],
),
));
}
}
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:manager/components/dotted_line.dart';
import 'package:manager/model/lookup_cycle.dart';
import 'package:manager/model/mr_report_model.dart';
import 'package:manager/services/dashboard_service.dart';
import 'package:manager/utils/debouncer.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:manager/utils/string_captialize.dart';
class MRPerformance extends StatefulWidget {
const MRPerformance({super.key});
#override
State<MRPerformance> createState() => _MRPerformanceState();
}
bool isFilter = false;
bool isPerformingRequest = false;
int pageNumber = 0;
String _chosenValue = '';
List<MRReportResult> users = [];
Future<List<String>?>? dropDownValue;
ScrollController _scrollController = ScrollController();
final _debouncer = Debouncer(milliseconds: 500);
class _MRPerformanceState extends State<MRPerformance> {
#override
void initState() {
super.initState();
_getMoreData(_chosenValue);
dropDownValue = getAllCategory();
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
pageNumber++;
_getMoreData(_chosenValue);
}
});
}
Future<List<String>?>? getAllCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('token')!;
var cycleResponse = await Dashboard().getAllCycle(token);
try {
if (cycleResponse.statusCode == 200) {
List<String> items = [];
var jsonData = json.decode(cycleResponse.body) as List;
List<LookUpCycle> lookupCycle = jsonData
.map<LookUpCycle>((json) => LookUpCycle.fromJson(json))
.toList();
items.add('Select');
for (var element in lookupCycle) {
if (element.name != null) {
items.add(element.name!);
}
}
return items;
}
} catch (ex) {
throw (ex.toString());
}
return null;
}
#override
void dispose() {
super.dispose();
_scrollController.dispose();
}
void _getMoreData(String searchCycle) async {
List<MRReportResult>? resultResponse = [];
if (!isPerformingRequest) {
setState(() {
isPerformingRequest = true;
});
SharedPreferences prefs = await SharedPreferences.getInstance();
String token = prefs.getString('token')!;
debugPrint(token);
var responseData =
await Dashboard().getMRReport(token, pageNumber, 10, searchCycle);
if (responseData.statusCode == 200) {
String data = responseData.body;
var decodedData = jsonDecode(data);
MRReportModel newEntries = MRReportModel.fromJson(decodedData);
if (newEntries.result == null) {
if (newEntries.result!.isEmpty) {
double edge = 50.0;
double offsetFromBottom =
_scrollController.position.maxScrollExtent -
_scrollController.position.pixels;
if (offsetFromBottom < edge) {
_scrollController.animateTo(
_scrollController.offset - (edge - offsetFromBottom),
duration: const Duration(milliseconds: 500),
curve: Curves.easeOut);
}
}
}
setState(() {
users.addAll(newEntries.result!);
isPerformingRequest = false;
});
}
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
appBar: AppBar(title: const Text('MR Performance')),
body: filterView());
}
void setFilterState() {
setState(() {
if (isFilter == true) {
isFilter = false;
} else {
isFilter = true;
}
});
}
Widget _buildProgressIndicator() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Opacity(
opacity: isPerformingRequest ? 1.0 : 0.0,
child: const CircularProgressIndicator(),
),
),
);
}
Widget filterView() {
return Column(
children: [
Row(
children: [
Visibility(
visible: isFilter ? true : false,
child: Flexible(
child: Card(
shape: RoundedRectangleBorder(
side: const BorderSide(color: Color(0XFFDCDCDC)),
borderRadius: BorderRadius.circular(10)),
elevation: 2,
child: Column(
children: [
Row(
children: [
Expanded(
child: TextField(
textInputAction: TextInputAction.search,
decoration: const InputDecoration(
border: InputBorder.none,
prefixIcon: InkWell(
child: Icon(Icons.search),
),
contentPadding: EdgeInsets.all(8.0),
hintText: 'Search ',
),
onChanged: (string) {
_debouncer.run(() {});
},
),
),
],
),
],
),
),
),
),
Visibility(
visible: isFilter ? false : true,
child: Flexible(
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
side: const BorderSide(color: Color(0XFFDCDCDC)),
borderRadius: BorderRadius.circular(10)),
child: Padding(
padding: const EdgeInsets.only(
left: 10,
),
child: FutureBuilder<List<String>?>(
future: dropDownValue,
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
if (snapshot.hasError) {
return const Text('Something wrong');
} else if (snapshot.hasData) {
var data = snapshot.data!;
return DropdownButtonHideUnderline(
child: DropdownButton<String>(
icon: const Icon(
Icons.expand_more_outlined,
size: 35,
color: Color(0XFF116AFF),
),
borderRadius: BorderRadius.circular(10),
isExpanded: true,
// value: _chosenValue.isNotEmpty ? _chosenValue : null,
elevation: 16,
style: const TextStyle(
color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.w400),
items: data.map((String value) {
return DropdownMenuItem(
value: value, child: Text(value));
}).toList(),
hint: Padding(
padding: const EdgeInsets.all(15),
child: Text(
_chosenValue.isEmpty
? 'Cycle'
: _chosenValue,
style: const TextStyle(
color: Colors.black,
fontSize: 16,
fontWeight: FontWeight.w400),
),
),
onChanged: (String? value) {
setState(() {
if (value != null) {
pageNumber = 0;
users.clear();
if (value == 'Select') {
_chosenValue = '';
} else {
_chosenValue = value;
}
_getMoreData(_chosenValue);
}
});
},
),
);
}
}
return const CircularProgressIndicator();
},
)),
),
),
),
InkWell(
onTap: () => {setFilterState()},
child: Card(
elevation: 4,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10)),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: isFilter
? const Icon(Icons.filter_alt, color: Color(0XFF116AFF))
: const Icon(
Icons.search,
color: Color(0XFF116AFF),
),
),
),
),
],
),
Expanded(
child: ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: users.length + 1,
controller: _scrollController,
itemBuilder: (BuildContext context, int index) {
if (index == users.length) {
return _buildProgressIndicator();
} else {
return cardView(users, index);
}
}),
),
],
);
}
Widget cardView(List<MRReportResult>? users, int index) {
return Card(
shape: RoundedRectangleBorder(
side: const BorderSide(color: Color(0XFFDCDCDC)),
borderRadius: BorderRadius.circular(10)),
margin: const EdgeInsets.all(8),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
decoration: BoxDecoration(
border: Border.all(
color: Colors.orange,
),
borderRadius: const BorderRadius.all(Radius.circular(20))),
margin: const EdgeInsets.all(10),
padding: const EdgeInsets.all(10),
child: Row(
children: [
Text(
'${users?[index].mRNumber}: ',
style: const TextStyle(
color: Colors.orange,
fontSize: 10,
fontWeight: FontWeight.w600),
),
Text(
'${users?[index].meterReaderName}'.toTitleCase(),
style: const TextStyle(
color: Colors.black,
fontSize: 10,
fontWeight: FontWeight.w400),
),
],
),
),
Padding(
padding: const EdgeInsets.only(left: 20),
child: Row(
children: [
const Text(
'Supervisor: ',
style: TextStyle(
color: Color(0XFF004AC6),
fontSize: 10,
fontWeight: FontWeight.w600),
),
Expanded(
child: Text(
'${users?[index].supervisor}'.toTitleCase(),
overflow: TextOverflow.fade,
style: const TextStyle(
color: Colors.black,
fontSize: 10,
fontWeight: FontWeight.w400),
),
),
],
),
),
const SizedBox(height: 10),
const MySeparator(),
const SizedBox(height: 10),
Padding(
padding: const EdgeInsets.only(left: 30, right: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Column(
children: [
Text(
'${users?[index].unreadPercenatge}%',
style: const TextStyle(
color: Colors.orange,
fontSize: 10,
fontWeight: FontWeight.w600),
),
const Text(
'Unread',
style: TextStyle(
color: Color(0XFF004AC6),
fontSize: 12,
fontWeight: FontWeight.w400),
)
],
)
],
),
Row(
children: [
Column(
children: [
Text(
'${users?[index].readPercenatge}%',
style: const TextStyle(
color: Colors.green,
fontSize: 10,
fontWeight: FontWeight.w600),
),
const Text(
'Read',
style: TextStyle(
color: Color(0XFF004AC6),
fontSize: 12,
fontWeight: FontWeight.w400),
)
],
)
],
),
Row(
children: [
Column(
children: [
Text(
'${users?[index].plusorMinusTwoReadPercentage}%',
style: const TextStyle(
color: Colors.green,
fontSize: 10,
fontWeight: FontWeight.w600),
),
const Text(
'+/- 2',
style: TextStyle(
color: Color(0XFF004AC6),
fontSize: 12,
fontWeight: FontWeight.w400),
)
],
)
],
),
Row(
children: [
Column(
children: [
Text(
'${users?[index].above32ReadPercentage}%',
style: const TextStyle(
color: Colors.orange,
fontSize: 10,
fontWeight: FontWeight.w600),
),
const Text(
'>32',
style: TextStyle(
color: Color(0XFF004AC6),
fontSize: 12,
fontWeight: FontWeight.w400),
)
],
)
],
),
],
),
),
],
),
),
);
}
}
════════ Exception caught by widgets library ═══════════════════════════════════
The following assertion was thrown building Builder:
A ScrollController was used after being disposed.
Once you have called dispose() on a ScrollController, it can no longer be used.
The relevant error-causing widget was
MaterialApp
lib/main.dart:13
When the exception was thrown, this was the stack
You have declared _getMoreData two times in init(), so remove it before _scrollController as shown below
void initState() {
super.initState();
_getMoreData(_chosenValue);-------------> remove this from here
dropDownValue = getAllCategory();
_scrollController.addListener(() {
if (_scrollController.position.pixels ==
_scrollController.position.maxScrollExtent) {
pageNumber++;
_getMoreData(_chosenValue);
}
});
}
OR
Declare ScrollController _scrollController = ScrollController(); in state class _MRPerformanceState as below code:
class _MRPerformanceState extends State<MRPerformance> {
ScrollController _scrollController = ScrollController();

Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast flutter

I'm trying to make a simple messaging application while using firebase and flutter, everything was working fine until I came to the message screen, but on this screen, I get the error that I will specify below. Do you know the solution for this?
Unhandled Exception: type 'Null' is not a subtype of type 'String' in type cast
I could not understand where I got the error, when I click on any user on the page where I listed the users, it gives this error directly.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_bubble/bubble_type.dart';
import 'package:flutter_chat_bubble/chat_bubble.dart';
import 'package:flutter_chat_bubble/clippers/chat_bubble_clipper_6.dart';
import 'package:ourchat/pallete.dart';
import 'package:ourchat/shared/utils.dart';
class ChatDetailPage extends StatefulWidget {
final String user;
const ChatDetailPage({
Key? key,
required this.user,
}) : super(key: key);
#override
_ChatDetailPageState createState() => _ChatDetailPageState();
}
class _ChatDetailPageState extends State<ChatDetailPage> {
TextEditingController messageController = TextEditingController();
final currentUserId = FirebaseAuth.instance.currentUser?.uid;
CollectionReference chats = FirebaseFirestore.instance.collection('chats');
var chatDocId;
var userData = {};
bool isLoading = false;
#override
void initState() {
super.initState();
getData();
checkUser();
}
void checkUser() async {
await chats
.where('users', isEqualTo: {userData['uid']: null, currentUserId: null})
.limit(1)
.get()
.then(
(QuerySnapshot querySnapshot) async {
if (querySnapshot.docs.isNotEmpty) {
setState(() {
chatDocId = querySnapshot.docs.single.id;
});
print(chatDocId);
} else {
await chats.add({
'users': {currentUserId: null, widget.user: null},
'names': {
currentUserId: FirebaseAuth.instance.currentUser?.displayName,
userData['uid']: userData['username']
}
}).then((value) => {chatDocId = value});
}
},
)
.catchError((error) {});
}
getData() async {
setState(() {
isLoading = true;
});
try {
var userSnap = await FirebaseFirestore.instance
.collection('users')
.doc(widget.user)
.get();
userData = userSnap.data()!;
print(userData);
setState(() {});
} catch (e) {
showSnackBar(
context,
e.toString(),
);
}
setState(() {
isLoading = false;
});
}
void sendMessage(String msg) {
if (msg == '') return;
chats.doc(chatDocId).collection('messages').add({
'createdOn': FieldValue.serverTimestamp(),
'uid': currentUserId,
'friendName': userData['username'],
'msg': msg
}).then((value) {
messageController.text = '';
});
}
bool isSender(String friend) {
return friend == currentUserId;
}
Alignment getAlignment(friend) {
if (friend == currentUserId) {
return Alignment.topRight;
}
return Alignment.topLeft;
}
#override
Widget build(BuildContext context) {
return isLoading
? const Center(
child: CircularProgressIndicator(),
)
: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(chatDocId)
.collection('messages')
.orderBy('createdOn', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Center(
child: Text("Bir şeyler yanlış gitti..."),
);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
color: kBlue,
),
);
}
if (snapshot.hasData) {
var data;
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
elevation: 0,
automaticallyImplyLeading: false,
backgroundColor: Colors.black,
flexibleSpace: SafeArea(
child: Container(
padding: EdgeInsets.only(right: 16),
child: Row(
children: <Widget>[
IconButton(
onPressed: () {
Navigator.pop(context);
},
icon: ImageIcon(
AssetImage("assets/icons/backicon.png"),
color: Colors.white,
),
),
SizedBox(
width: 2,
),
CircleAvatar(
backgroundImage:
NetworkImage(userData['photoUrl'].toString()),
maxRadius: 20,
),
SizedBox(
width: 12,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
userData['username'].toString(),
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Colors.white),
),
SizedBox(
height: 6,
),
Text(
userData['bio'].toString(),
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 13,
),
),
],
),
),
Icon(
Icons.settings,
color: Colors.white,
),
],
),
),
),
),
body: Stack(
children: <Widget>[
ListView(
reverse: true,
children: snapshot.data!.docs.map(
(DocumentSnapshot documentSnapshot) {
data = documentSnapshot.data()!;
print(documentSnapshot.toString());
print(data['msg']);
return Padding(
padding:
const EdgeInsets.symmetric(horizontal: 8.0),
child: ChatBubble(
clipper: ChatBubbleClipper6(
nipSize: 0,
radius: 0,
type: isSender(data['uid'].toString())
? BubbleType.sendBubble
: BubbleType.receiverBubble,
),
alignment: getAlignment(data['uid'].toString()),
margin: EdgeInsets.only(top: 20),
backGroundColor:
isSender(data['uid'].toString())
? Color(0xFF08C187)
: Color(0xffE7E7ED),
child: Container(
constraints: BoxConstraints(
maxWidth:
MediaQuery.of(context).size.width * 0.7,
),
child: Column(
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.start,
children: [
Text(data['msg'],
style: TextStyle(
color: isSender(data['uid']
.toString())
? Colors.white
: Colors.black),
maxLines: 100,
overflow: TextOverflow.ellipsis)
],
),
Row(
mainAxisAlignment:
MainAxisAlignment.end,
children: [
Text(
data['createdOn'] == null
? DateTime.now().toString()
: data['createdOn']
.toDate()
.toString(),
style: TextStyle(
fontSize: 10,
color: isSender(
data['uid'].toString())
? Colors.white
: Colors.black),
)
],
)
],
),
),
),
);
},
).toList(),
),
Align(
alignment: Alignment.bottomLeft,
child: Container(
padding:
EdgeInsets.only(left: 10, bottom: 10, top: 10),
height: 60,
width: double.infinity,
color: Colors.black,
child: Row(
children: <Widget>[
GestureDetector(
onTap: () {},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: kBlue,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.add,
color: Colors.white,
size: 26,
),
),
),
SizedBox(
width: 15,
),
Expanded(
child: TextField(
controller: messageController,
style: TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: "Lütfen mesaj yazınız.",
labelStyle:
TextStyle(color: Colors.white),
hintStyle: TextStyle(color: Colors.white),
border: InputBorder.none),
),
),
SizedBox(
width: 15,
),
GestureDetector(
onTap: () {
sendMessage(messageController.text);
},
child: Container(
height: 40,
width: 40,
decoration: BoxDecoration(
color: kBlue,
borderRadius: BorderRadius.circular(30),
),
child: Icon(
Icons.send,
color: Colors.white,
size: 20,
),
),
),
],
),
),
),
],
),
);
}
return null!;
},
);
}
}

Null check operator used on a null value when submitting a form

I'm trying to send form data to an API after pressing the submit button for a form but each time I'm getting an error "Null check operator used on a null value" and does not send the data. Below is my code.
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
//import 'package:flutter/services.dart';
import 'package:keilvog/Screens/6kg_cylinder_screen.dart';
import 'package:keilvog/Widget/edit_image.dart';
import 'package:keilvog/Widget/header.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:http/http.dart' as http;
import 'package:keilvog/Widget/validators.dart';
import 'package:shared_preferences/shared_preferences.dart';
// ignore: non_constant_identifier_names
Future<dynamic> UploadData(
{String? brand,
String? capacity,
String? amount,
//File? image
}) async {
final SharedPreferences preferences = await SharedPreferences.getInstance();
final String? myJWT = preferences.getString('jwt');
Map<String, dynamic> token = jsonDecode(myJWT!);
Map<String, dynamic> body = {
'brand': brand,
'capacity': capacity,
'amount': int.parse(amount!),
// 'image':
// 'data:image/png;base64,' + base64Encode(image!.readAsBytesSync()),
};
var url = Uri.parse('https://kelivog.com/sell/cylinder');
var myRequest = http.MultipartRequest('POST', url);
// var stream = http.ByteStream((image!.openRead()));
// var length = await image.length();
myRequest.headers.addAll(
{"Authorization": token['token'], "Content-Type": "application/json"});
// var multipartFile = await http.MultipartFile.fromPath(
// 'photo', image.path);
//myRequest.files.add(multipartFile);
http.StreamedResponse response = await myRequest.send();
final responseString = await response.stream.bytesToString();
if (kDebugMode) {
print(response.statusCode);
}
if (kDebugMode) {
print(responseString);
}
if (response.statusCode == 200) {
if (kDebugMode) {
print(jsonEncode(body));
}
final myResponse = await http.Client().get(
Uri.parse('https://kelivog.com/sell/cylinder'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Authorization': token['token']
},
);
if (myResponse.statusCode == 200) {
final myData = json.decode(myResponse.body);
myData['data'].length == 0
? await http.Client()
.post(
Uri.parse('https://kelivog.com/sell/61ed7fa0ce1fd097aa002a3d'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Authorization': token['token']
},
body: jsonEncode(body),
)
.then((value) => {
if (value.statusCode == 200)
// ignore: avoid_print
{
print("POST Successful"),
// ignore: avoid_print
print(jsonEncode(body))
}
else
// ignore: avoid_print
{print("FAILED")}
})
: await http.Client()
.put(
Uri.parse('https://kelivog.com/sell/61ed7fa0ce1fd097aa002a3d'),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Authorization': token['token']
},
body: jsonEncode(body),
)
.then((value) => {
if (value.statusCode == 200)
{
// ignore: avoid_print
print("PUT Successful"),
// ignore: avoid_print
print(jsonEncode(body)),
}
else
// ignore: avoid_print
{print("FAILED")}
});
return myResponse.statusCode;
} else {
if (kDebugMode) {
print(myResponse.statusCode);
}
throw Exception('Failed to update Profile.' '${myResponse.body}');
}
} else {
if (kDebugMode) {
print(response.statusCode);
}
if (kDebugMode) {
print("ERROR");
}
}
}
class SellDetails extends StatefulWidget {
const SellDetails({Key? key}) : super(key: key);
#override
State<SellDetails> createState() => _SellDetailsState();
}
class _SellDetailsState extends State<SellDetails> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final brandController = TextEditingController();
final capacityController = TextEditingController();
final amountController = TextEditingController();
//File? image;
bool isLoading = false;
#override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("images/background.jpg"), fit: BoxFit.cover)
),
child: Scaffold(
body: SingleChildScrollView(
child: Column(
children: [
header(),
SizedBox(height: 20.h),
//const EditImage(),
Container(
width: 190.w,
height: 125.h,
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage("images/others.png"), fit: BoxFit.cover,
)
),
),
SizedBox(height: 30.h),
Form(
key: _formKey,
//autovalidateMode: AutovalidateMode.onUserInteraction,
child: Container(
width: 350.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15.r)),
image: const DecorationImage(
image: AssetImage("images/background.jpg"),
fit: BoxFit.fitWidth,
alignment: Alignment.topCenter,
),
boxShadow: const [
BoxShadow(color: Colors.grey, spreadRadius: 2),
],
),
child: Column(
children: [
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("BRAND",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
child: TextFormField(
//textAlignVertical: TextAlignVertical.center,
validator: brandValidator,
controller: brandController,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
//const Divider(indent: 15, endIndent: 15, thickness: 2),
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("CAPACITY",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
child: TextFormField(
validator: capacityValidator,
controller: capacityController,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 12.h, horizontal: 16.w),
child: Row(
children: [
Expanded(
child: Text("AMOUNT",
style: TextStyle(
fontSize: 18.sp,
fontWeight: FontWeight.bold,
)),
),
SizedBox(width: 1.w),
Expanded(
child: Container(
width: 90.w,
height: 40.h,
decoration: BoxDecoration(
color: Colors.yellow[600],
borderRadius: BorderRadius.circular(15)),
child: Center(
child: TextFormField(
validator: amountValidator,
controller: amountController,
keyboardType: TextInputType.number,
showCursor: false,
style: const TextStyle(
fontSize: 20.0,
height: 2.0,
color: Colors.black,
),
decoration: const InputDecoration(
contentPadding: EdgeInsets.only(
top: 1.0, bottom: 100.0, left: 8.0),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(
Radius.circular(15.0)),
),
),
),
),
),
),
],
),
),
],
),
),
),
SizedBox(height: 40.h),
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
if (kDebugMode) {
print('Imageeee');
}
//if (image != null) {
await UploadData(
//image: image,
brand: brandController.text,
capacity: capacityController.text,
amount: amountController.text,
// serviceFee: double.parse(serviceFeeController.text),
// takeHome: double.parse(takeHomeController.text),
);
// }
// else {
// // ignore: avoid_print
// print('You have not added an image');
// }
if (isLoading) {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
const SixCylindersListsScreen(
item: '',
id: '',
title: '',
)));
} else {
throw Exception('Failed to upload details.');
}
}
},
child: Text(
'UPLOAD',
style: TextStyle(
color: Colors.yellow[600],
fontSize: 22.sp,
fontWeight: FontWeight.w700,
),
),
style: ElevatedButton.styleFrom(
elevation: 5,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15.r),
),
fixedSize: Size(150.w, 50.h),
primary: const Color(0xff261005),
),
),
],
),
),
),
);
}
}
I have commented out some parts of the code while trying to debug but still getting the same error. The error points to the line with await UploadData
ElevatedButton(
onPressed: () async {
if (_formKey.currentState!.validate()) {
if (kDebugMode) {
print('Imageeee');
}
//////////THE ERROR POINTS HERE////////
await UploadData(
brand: brandController.text,
capacity: capacityController.text,
amount: amountController.text,
);
This error occurs when a bang (!) operator is used on a nullable instance that hasn't been initialized. Check the logs which line on your code the error is thrown.
To solve this issue, you can initialize a default value for the variable
String foo = 'defaultValue';
if(newValue != null){
foo = newValue;
}
bar(foo);
...or set a default fallback value for the nullable variable if the value is null with (??).
String? foo;
bar(foo?.getValue() ?? 'defaultValue');

Flutter, How to use laravel API for flutter login

Im new to flutter and currently work as an intern in a small company, I'm trying to get API from laravel and try to login in flutter. Is there anyone can assist me to have a look on my code? I will write them below.
I'm trying to test it without token, but on online tutorial everyone is having token.
api.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
class Network{
final String _url = 'http://192.168.0.138:8000/api/';
var token;
_getToken() async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
token = jsonDecode(localStorage.getString('token'))['token'];
}
authData(data, apiUrl) async {
var fullUrl = _url + apiUrl;
return await http.post(
fullUrl,
body: jsonEncode(data),
headers: _setHeaders()
);
}
getData(apiUrl) async {
var fullUrl = _url + apiUrl;
await _getToken();
return await http.get(
fullUrl,
headers: _setHeaders()
);
}
_setHeaders() => {
'Content-type' : 'application/json',
'Accept' : 'application/json',
'Authorization' : 'Bearer $token'
};
}
Login_Screen
import 'package:ezymember/screens/home_screen.dart';
import 'package:ezymember/screens/register_screen.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:ezymember/network_utils/api.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({Key key}) : super(key: key);
#override
_LoginScreenState createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
bool _isLoading = false;
final _formKey = GlobalKey<FormState>();
var member_email;
var member_password;
final _scaffoldKey = GlobalKey<ScaffoldState>();
_showMsg(msg) {
final snackBar = SnackBar(
content: Text(msg),
action: SnackBarAction(
label: 'Close',
onPressed: () {
// Some code to undo the change!
},
),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Stack(
children: <Widget>[
Container(
padding: const EdgeInsets.fromLTRB(15.0, 110.0, 0.0, 0.0),
child: const Text('Hello',
style:
TextStyle(fontSize: 80.0, fontWeight: FontWeight.bold)),
),
Container(
padding: const EdgeInsets.fromLTRB(16.0, 175.0, 0.0, 0.0),
child: const Text('There',
style:
TextStyle(fontSize: 80.0, fontWeight: FontWeight.bold)),
),
Container(
padding: const EdgeInsets.fromLTRB(220.0, 175.0, 0.0, 0.0),
child: const Text('.',
style: TextStyle(
fontSize: 80.0,
fontWeight: FontWeight.bold,
color: Colors.blue)),
)
],
),
Container(
padding: const EdgeInsets.only(top: 35.0, left: 20.0, right: 20.0),
child: Form(
key: _formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'EMAIL',
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
),
validator: (emailValue) {
if (emailValue.isEmpty) {
return 'Please enter email';
}
member_email = emailValue;
return null;
},
),
TextFormField(
keyboardType: TextInputType.text,
decoration: const InputDecoration(
labelText: 'PASSWORD',
labelStyle: TextStyle(
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
color: Colors.grey),
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
),
validator: (passwordValue) {
if (passwordValue.isEmpty) {
return 'Please Enter Password';
}
member_password = passwordValue;
return null;
},
),
Padding(
padding: const EdgeInsets.all(10.0),
child: FlatButton(
child: Padding(
padding: const EdgeInsets.only(
top: 8, bottom: 8, left: 10, right: 10),
child: Text(
_isLoading ? 'Proccessing...' : 'Login',
textDirection: TextDirection.ltr,
style: const TextStyle(
color: Colors.white,
fontSize: 20.0,
decoration: TextDecoration.none,
fontWeight: FontWeight.normal,
),
),
),
color: Colors.blue,
disabledColor: Colors.grey,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20.0)),
onPressed: () {
if (_formKey.currentState.validate()) {
_login();
}
},
),
),
],
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'New to EzyMember ?',
style: TextStyle(fontFamily: 'Montserrat'),
),
const SizedBox(width: 5.0),
InkWell(
onTap: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) => RegisterPage()));
},
child: const Text(
'Register',
style: TextStyle(
color: Colors.blue,
fontFamily: 'Montserrat',
fontWeight: FontWeight.bold,
decoration: TextDecoration.underline),
),
),
],
),
],
),
),
);
}
void _login() async {
setState(() {
_isLoading = true;
});
var data = {'email': member_email, 'password': member_password};
var res = await Network().authData(data, '/login');
var body = json.decode(res.body);
if (body['success']) {
SharedPreferences localStorage = await SharedPreferences.getInstance();
localStorage.setString('token', json.encode(body['token']));
localStorage.setString('user', json.encode(body['user']));
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const HomeScreen()),
);
} else {
_showMsg(body['message']);
}
setState(() {
_isLoading = false;
});
}
}

When routing to another page I get "There are multiple heroes that share the same tag within a subtree"

I am trying to navigate from one screen to another with route. When I hit the button for the page to move to the route provided I get the error:
I/flutter ( 8790): Another exception was thrown: There are multiple heroes that share the same tag within a subtree.
Sharing with you the source code:
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_counter/flutter_counter.dart';
import 'package:gender_selection/gender_selection.dart';
import 'package:group_chats/addContactUI.dart';
import 'package:group_chats/addPhone.dart';
import 'package:group_chats/letGoUI.dart';
import 'package:http/http.dart' as http;
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Animation/FadeAnimation.dart';
import 'Model/insertUserModel.dart';
class AddProfileUI extends StatefulWidget {
final List<String> listFriends;
final String phone;
AddProfileUI(this.listFriends, this.phone);
#override
_AddProfileUIState createState() => _AddProfileUIState();
}
class _AddProfileUIState extends State<AddProfileUI> {
File _image;
final picker = ImagePicker();
final _formKey = GlobalKey<FormState>();
String name = "";
String city = "";
TextEditingController dobController = TextEditingController();
bool single = false;
Gender gender;
final _scaffoldKey = GlobalKey<ScaffoldState>();
int defaultValue = 18;
List<String> selectedContact;
SharedPreferences prefs;
bool _loading = true;
Future initPrefs() async {
prefs = await SharedPreferences.getInstance();
}
uploadImage(String userId) async {
try {
FormData formData = new FormData.fromMap({
"file":
await MultipartFile.fromFile(_image.path, filename: "$userId.jpg"),
});
var response = await Dio().post(
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/upload_profile/$userId",
data: formData);
if (response.statusCode == 200)
return response.data;
else
return null;
} catch (e) {
print(e.toString());
return null;
}
}
Future<InsertUserModel> insertData() async {
try {
for (int i = 0; i < selectedContact.length; i++) {
if (selectedContact[i][0] == "0") {
selectedContact[i] = selectedContact[i].replaceRange(0, 1, "+972");
}
}
var body = jsonEncode({
"gender": gender.index == 0 ? "male" : "female",
"city": city,
"last_login": {},
"friends": selectedContact ?? [],
"single": single,
"name": name,
"phone_number": widget.phone,
"age": defaultValue
});
final String apiUrl =
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/users/${AddPhoneUI.uid}";
final response = await http.post(apiUrl,
headers: {"content-type": "application/json"}, body: body);
if (response.statusCode == 200) {
final responseString = response.body;
return insertUserModelFromJson(responseString);
}
} catch (e) {
setState(() {
_loading = false;
});
}
}
getUserData() async {
try {
final String apiUrl =
"https://us-central1-app-backend-fc090.cloudfunctions.net/webApi/api/v1/users/";
final response = await http.get(apiUrl);
if (response.statusCode == 200) {
final responseString = response.body;
return insertUserModelFromJson(responseString);
}
} catch (e) {
setState(() {
_loading = false;
});
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.red,
content: Text('Error: ${e.toString()}'),
duration: Duration(milliseconds: 2500),
));
}
}
Future<void> _selectStartingDate(BuildContext context) async {
DateTime selectedDate = DateTime.now();
final DateTime picked = await showDatePicker(
context: context,
initialDate: selectedDate,
firstDate: DateTime(1950),
lastDate: DateTime(
DateTime.now().year, DateTime.now().month, DateTime.now().day),
);
if (picked != null && picked != selectedDate)
setState(() {
selectedDate = picked;
dobController.text = selectedDate.year.toString() +
"-" +
selectedDate.month.toString() +
"-" +
selectedDate.day.toString();
});
}
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
_image = File(pickedFile.path);
});
}
showPopUp(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
shape:
OutlineInputBorder(borderRadius: BorderRadius.circular(14.0)),
content: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
height: 20.0,
),
Text(
"My Profile",
style: TextStyle(
fontSize: 27.0, fontWeight: FontWeight.w600),
),
SizedBox(
height: 30.0,
),
RichText(
text: TextSpan(
text: "Your friends will be able to\nsee ",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
children: <TextSpan>[
TextSpan(
text: 'only',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500)),
TextSpan(text: 'your picture and\name.'),
],
)),
SizedBox(
height: 10.0,
),
RichText(
text: TextSpan(
text: "Other fields are used for\n",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
children: <TextSpan>[
TextSpan(
text: 'research issues',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500)),
TextSpan(text: "only."),
],
)),
SizedBox(
height: 10.0,
),
RichText(
text: TextSpan(
text: "Please fill all the fields.",
style: TextStyle(
color: Colors.black,
fontSize: 18.0,
),
)),
SizedBox(
height: 80.0,
),
MaterialButton(
shape: OutlineInputBorder(
borderSide: BorderSide(width: 1.0)),
color: Colors.white38,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
"Ok, got it",
style: TextStyle(fontSize: 18.0),
),
),
onPressed: () {
Navigator.pop(context);
},
),
],
),
),
));
}
#override
void initState() {
super.initState();
selectedContact = widget.listFriends;
initPrefs();
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: SafeArea(
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(right: 10.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {},
),
GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => AddContactUI(),
)).then((value) {
setState(() {
selectedContact = value;
});
});
},
child: Column(
children: [
Icon(
Icons.supervisor_account,
size: 40.0,
),
Text("Add Friends"),
],
),
)
],
),
),
Container(
child: GestureDetector(
onTap: () async {
await getImage();
},
child: CircleAvatar(
radius: 60.0,
backgroundImage: _image != null
? Image.file(_image).image
: Image.asset("assets/empty.png").image,
backgroundColor: Colors.transparent,
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: FadeAnimation(
1.7,
Form(
key: _formKey,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(
color: Color(0xff5E17EB).withOpacity(0.3),
blurRadius: 20,
offset: Offset(0, 10),
)
]),
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[200]))),
child: TextFormField(
textInputAction: TextInputAction.next,
onFieldSubmitted: (_) =>
FocusScope.of(context).nextFocus(),
onChanged: (val) {
setState(() {
name = val;
});
},
validator: (val) =>
val.isEmpty ? "Enter Name" : null,
decoration: InputDecoration(
border: InputBorder.none,
hintText: "Name",
hintStyle: TextStyle(color: Colors.grey)),
),
),
Container(
decoration: BoxDecoration(
border: Border(
bottom:
BorderSide(color: Colors.grey[200]))),
padding: EdgeInsets.all(10),
child: TextFormField(
textInputAction: TextInputAction.next,
keyboardType: TextInputType.text,
onChanged: (val) {
setState(() {
city = val;
});
},
validator: (val) {
if (val.isEmpty) return "Enter City";
// if (val.length < 6)
// return "Password should be at least 6 characters";
return null;
},
decoration: InputDecoration(
border: InputBorder.none,
hintText: "City",
hintStyle: TextStyle(color: Colors.grey)),
),
),
Container(
height: 140.0,
padding: EdgeInsets.all(10),
child: GenderSelection(
selectedGender: gender,
maleText: "", //default Male
femaleText: "", //default Female
linearGradient: LinearGradient(colors: [
Colors.indigo,
Colors.black
]), //List: [Colors.indigo, Colors.black]
selectedGenderIconBackgroundColor:
Colors.indigo, // default red
checkIconAlignment:
Alignment.centerRight, // default bottomRight
selectedGenderCheckIcon:
null, // default Icons.check
onChanged: (Gender gender) {
this.gender = gender;
print(this.gender);
},
equallyAligned: true,
animationDuration: Duration(milliseconds: 400),
isCircular: true, // default : true,
isSelectedGenderIconCircular: true,
opacityOfGradient: 0.6,
padding: const EdgeInsets.all(3),
size: 120, //default : 120
),
),
SizedBox(
height: 10.0,
),
Row(
children: [
Checkbox(
value: single,
onChanged: (value) {
setState(() {
single = !single;
});
},
),
Text(
"Are you Single?",
style: TextStyle(fontSize: 16.0),
)
],
),
Padding(
padding: const EdgeInsets.all(14.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
"Age:",
style: TextStyle(fontSize: 18.0),
),
Counter(
initialValue: defaultValue,
buttonSize: 35.0,
textStyle: TextStyle(fontSize: 25.0),
minValue: 0,
color: Colors.black,
maxValue: 80,
step: 1,
decimalPlaces: 0,
onChanged: (value) {
// get the latest value from here
setState(() {
defaultValue = value;
});
},
),
],
),
),
],
),
),
),
),
),
SizedBox(
height: 20.0,
),
FadeAnimation(
1.9,
MaterialButton(
shape: OutlineInputBorder(borderSide: BorderSide(width: 1.0)),
color: Colors.black,
child: Padding(
padding: const EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
"Next",
style: TextStyle(
fontSize: 18.0,
color: Colors.white,
),
),
),
onPressed: () async {
if (_formKey.currentState.validate()) {
InsertUserModel result = await insertData();
// var imageResult = await uploadImage(result.id);
print(result.data[0].id);
if (_image != null) {
await uploadImage(result.data[0].id);
}
setState(() {
_loading = false;
});
if (result != null) {
await prefs.setString("userID", result.data[0].id);
final snackBar = SnackBar(
content: Text(
result.message,
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.green,
duration: Duration(milliseconds: 2000),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LetGoUI(result.data[0].id),
));
} else {
final snackBar = SnackBar(
content: Text(
"Here is some error, please try again later!",
style: TextStyle(color: Colors.white),
),
backgroundColor: Colors.red,
duration: Duration(milliseconds: 2000),
);
_scaffoldKey.currentState.showSnackBar(snackBar);
}
}
},
),
)
],
),
),
),
);
}
}
I really don't understand what is the problem because I'm not using any Heros and not have double FloatingActionButton.
How do I solve this?
Thanks
There might be problem with showing snackbar while navigating. you should remove that problem by calling following method before navigating.
void removeSnackBarCallsBeforeNavigation() {
ScaffoldMessenger.of(context).removeCurrentSnackBar();
}