I am building an app for Covid-19. while building the app I am calling a API via a function and want to load the content only after the API is successfully hit.
In the debug mode, everything is working fine and contents gets loaded after data is fetched from api till then it shows loading screen but in release mode, but it gets stuck in loading screen. Here is the sample code
import 'package:covid_19/widgets/counter.dart';
import 'package:covid_19/widgets/my_header.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:covid_19/API/api.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
import 'constant.dart';
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final controller = ScrollController();
double offset = 0;
String countryname="All";
bool loaded=false;
List country=[];
String totalcase="0";
String infectedcase="0";
String deathcase="0";
String recoveredcase="0";
String newcase="0";
String activecase="0";
String criticalcase="0";
String newdeathcase="0";
String testtotal="0";
String day="";
String time="";
List stat=[];
Future getcountry() async{
final data=await getcountries.getdata();
setState(() {
country=data;
});
getstatss();
}
Future getstatss() async{
final data=await getstats.getdata();
setState(() {
stat=data;
});
for(int i=0;i<stat.length;i++){
if(countryname==stat[i]['country']){
setState(() {
totalcase=stat[i]['cases']['total'].toString();
recoveredcase=stat[i]['cases']['recovered'].toString();
newcase=stat[i]['cases']['new'].toString();
activecase=stat[i]['cases']['active'].toString();
criticalcase=stat[i]['cases']['critical'].toString();
newdeathcase=stat[i]['deaths']['new'].toString();
deathcase=stat[i]['deaths']['total'].toString();
testtotal=stat[i]['tests']['total'].toString();
day=stat[i]['day'].toString();
time=stat[i]['time'].toString();
});
break;
}
}
setState(() {
loaded=true;
});
}
Future filterdata() async{
totalcase="0";
infectedcase="0";
deathcase="0";
recoveredcase="0";
newcase="0";
activecase="0";
criticalcase="0";
newdeathcase="0";
testtotal="0";
day="";
time="";
setState(() {
loaded=false;
});
for(int i=0;i<stat.length;i++){
print(stat[i]);
if(countryname==stat[i]['country']){
print(countryname);
totalcase=stat[i]['cases']['total'].toString();
recoveredcase=stat[i]['cases']['recovered'].toString();
newcase=stat[i]['cases']['new'].toString();
activecase=stat[i]['cases']['active'].toString();
criticalcase=stat[i]['cases']['critical'].toString();
newdeathcase=stat[i]['deaths']['new'].toString();
deathcase=stat[i]['deaths']['total'].toString();
testtotal=stat[i]['tests']['total'].toString();
day=stat[i]['day'].toString();
time=stat[i]['time'].toString();
}
}
setState(() {
loaded=true;
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
getcountry();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async => false,
child: MaterialApp(
title: "Covid 19",
theme: new ThemeData(
primaryColor: Colors.blue,
primaryColorLight: Color.fromRGBO(111, 196, 242, 1),
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
home: Scaffold(
body: SingleChildScrollView(
controller: controller,
child:Column(
children: <Widget>[
MyHeader(
image: "assets/icons/Drcorona.svg",
textTop: "You just Need",
textBottom: "to stay at home.",
offset: offset,
),
loaded?Container(
margin: EdgeInsets.symmetric(horizontal: 20),
padding: EdgeInsets.symmetric(vertical: 10, horizontal: 20),
height: 60,
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25),
border: Border.all(
color: Color(0xFFE5E5E5),
),
),
child: Row(
children: <Widget>[
SvgPicture.asset("assets/icons/maps-and-flags.svg"),
SizedBox(width: 20),
Expanded(
child: DropdownButton(
isExpanded: true,
underline: SizedBox(),
icon: SvgPicture.asset("assets/icons/dropdown.svg"),
value: countryname,
items: country.map<DropdownMenuItem<dynamic>>((dynamic value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
onChanged: (value) {
setState(() {
countryname=value;
});
filterdata();
},
),
),
],
),
):SizedBox(),
SizedBox(height: 20),
loaded?Padding(
padding: EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
RichText(
text: TextSpan(
children: [
TextSpan(
text: "Case Update\n",
style: kTitleTextstyle,
),
TextSpan(
text: time!=null||time==""?"Newest update ${time.split("T")[0]} ${time.split("T")[1].split("+")[0]}":"Todays Update",
style: TextStyle(
color: kTextLightColor,
),
),
],
),
),
Spacer(),
Text(
"See details",
style: TextStyle(
color: kPrimaryColor,
fontWeight: FontWeight.w600,
),
),
],
),
SizedBox(height: 20),
Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 4),
blurRadius: 30,
color: kShadowColor,
),
],
),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Counter(
color: kInfectedColor,
sizeup:1.5,
number: totalcase=="null"?int.parse("0"):int.parse(totalcase),
title: "Total Cases",
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Counter(
color: kInfectedColor,
number: activecase=="null"?int.parse("0"):int.parse(activecase),
sizeup: 1.2,
title: "Infected",
),
Counter(
color: kDeathColor,
number: deathcase=="null"?int.parse("0"):int.parse(deathcase),
sizeup: 1.2,
title: "Deaths",
),
Counter(
color: kRecovercolor,
number: recoveredcase=="null"?int.parse("0"):int.parse(recoveredcase),
sizeup: 1.2,
title: "Recovered",
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Counter(
color: kInfectedColor,
number: newcase=="null"?int.parse("0"):int.parse(newcase),
sizeup: 1,
title: "New Case",
),
Counter(
color: kDeathColor,
number: newdeathcase=="null"?int.parse("0"):int.parse(newdeathcase),
sizeup: 1,
title: "New Death",
),
Counter(
color: kRecovercolor,
number: testtotal=="null"?int.parse("0"):int.parse(testtotal),
sizeup: 1,
title: "Total Tests",
),
],
),
],
),
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Text(
"Spread of Virus",
style: kTitleTextstyle,
),
Text(
"See details",
style: TextStyle(
color: kPrimaryColor,
fontWeight: FontWeight.w600,
),
),
],
),
Container(
margin: EdgeInsets.only(top: 20),
padding: EdgeInsets.all(20),
height: 178,
width: double.infinity,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white,
boxShadow: [
BoxShadow(
offset: Offset(0, 10),
blurRadius: 30,
color: kShadowColor,
),
],
),
child: Image.asset(
"assets/images/map.png",
fit: BoxFit.contain,
),
),
],
),
):Center(child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
Text("Connecting",style: TextStyle(fontSize: 20),),
SizedBox(height: 50,),
],
),),
],
)),
),
),
);
}
}
I am quite sure that the problem is in this block of code. It might be a good idea to add some != null checks or at min try-catch :)
if(countryname==stat[i]['country']){
print(countryname);
totalcase=stat[i]['cases']['total'].toString();
recoveredcase=stat[i]['cases']['recovered'].toString();
newcase=stat[i]['cases']['new'].toString();
activecase=stat[i]['cases']['active'].toString();
criticalcase=stat[i]['cases']['critical'].toString();
newdeathcase=stat[i]['deaths']['new'].toString();
deathcase=stat[i]['deaths']['total'].toString();
testtotal=stat[i]['tests']['total'].toString();
day=stat[i]['day'].toString();
time=stat[i]['time'].toString();
}