I am just writing a simple application using flutter. I came across a situation where I need to display widgets conditionally. I am fetching data using app script API from Google Sheets. I want to show the "Loading..." text during loading and want to hide it after completing the request.
The following code works as expected if I run it within/using Android Studio. But If I build the APK and install it on my device, only "Loading..." text is showing on the screen, although the data is loaded and stored in listResponse.
class HomePage extends StatefulWidget {
const HomePage({Key? key, required this.title, required this.baseUrl}) : super(key: key);
final String title;
final String baseUrl;
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
late List listResponse = [];
Future categories() async {
var url = widget.baseUrl 'categories';
http.Response response = await http.get(Uri.parse(url));
if(response.statusCode == 200){
setState(() {
listResponse = json.decode(response.body);
print(listResponse.toString());
});
}
}
@override
void initState(){
categories();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TopBar(title: widget.title),
body: listResponse.isEmpty ? Center(child: Text('Loading...')) : Center(child: Text(listResponse.toString()))
);
}
}
I have searched for the solution and found some examples on stackoverflow. What could be the issue as the app is running as expected in development. I appreciate the help.
CodePudding user response:
You can use condition value to show loading and result, Take bool isSuccess = false
and in your statusCode==200 setState
make it isSuccess = true
class _HomePageState extends State<HomePage> {
late List listResponse = [];
bool isSuccess = false;
Future categories() async {
var url = widget.baseUrl 'categories';
http.Response response = await http.get(Uri.parse(url));
if(response.statusCode == 200){
setState(() {
listResponse = json.decode(response.body);
isSuccess = true;
print(listResponse.toString());
});
}
}
@override
void initState(){
categories();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: TopBar(title: widget.title),
body: isSuccess ? Center(child: Text('Loading...')) : Center(child: Text(listResponse.toString()))
);
}
It will work fine when data is fetched.
Or you can also use FutureBiulder
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: categories(),
builder: (context, snapshot) {
if (snapshot.hasError) {
return Text(
'There was an error :(',
style: Theme.of(context).textTheme.headline,
);
} else if (snapshot.hasData) {
var count = json.decode(snapshot.data).length;
return Center(child: Text(listResponse.toString()));
} else {
return Center(child: Text('Loading...'))
}
});
}