first of all, sorry for the lack of information in the title, I just couldn't think of anything better to write.
My problem is that I'm parsing JSON data from an online API and sometimes it displays what I want it to display, and sometimes it doesn't... here is the code:
(The first code block is the class of what I'll be using in the second block, which is the important part and probably where I think the problem is coming from)
import 'dart:convert';
import 'package:http/http.dart' as http;
class CanteenInfo {
final String canteenUrl = 'https://sigarra.up.pt/feup/pt/mob_eme_geral.cantinas';
List canteenMenu = [];
var data;
String workingHours = "yes";
CanteenInfo() {
getWebsiteData();
}
Future getWebsiteData() async {
var response = await http.get(Uri.parse(canteenUrl));
if (response.statusCode == 200) {
data = json.decode(response.body);
workingHours = data[3]["horario"];
print("Hours: " workingHours);
}
else {
throw Exception('Failed to read $canteenUrl');
}
}
}
class WorkingHours extends StatefulWidget {
const WorkingHours({Key? key}) : super(key: key);
@override
State<WorkingHours> createState() => _WorkingHours();
}
class _WorkingHours extends State<WorkingHours> {
String hours = "yes";
CanteenInfo canteen = CanteenInfo();
void getHours() {
setState(() {
hours = canteen.getHours();
});
}
@override
Widget build(BuildContext context) {
getHours();
return Scaffold(
appBar: AppBar(
title: Text('EasyFood'),
),
body: Center(
child: Container (
margin: const EdgeInsets.only(top: 100),
child: Column(
children: <Widget>[
Text(
'Lunch: ' hours,
style: const TextStyle(
fontSize: 20
)
),
],
),
),
),
);
}
}
If I haven't made my problem clear, when I run the code, sometimes it displays the text as "Lunch: yes" and sometimes as the correct thing, which is "Lunch: 11:30 às 14:00".
By my understanding, I think what's happening is that sometimes the code can get the API information and time and has time to change the variable before the page loads, and sometimes it doesn't. Either way, I don't know how to fix it so if anyone has any idea I would relly appreciate the help :)
Thanks alot for taking the time to read this
CodePudding user response:
I'm not sure if getHours method exists in CanteenInfo. But you probably need to override initState method in your stateful widget and call
canteen.getWebsiteData().then((value) {
setState(() => hours = canteen.workingHours);
});
or something like that depending on which method returns data from API
CodePudding user response:
A good decision will be to wait CanteenInfo object "canteen" to be initialized, smth like this:
var flag = false;
loadData()async{
flag = true;
canteen = CanteenInfo();
await getHours();
setState((){flag=false;});
}
Widget build(BuildContext context) {
if (hours == "yes" && !flag)
loadData();
if (flag)
return Scaffold(body:CircularProgressIndicator());
return Scaffold(
appBar: AppBar(
title: Text('EasyFood'),
),
body: Center(
child: Container (
margin: const EdgeInsets.only(top: 100),
child: Column(
children: <Widget>[
Text(
'Lunch: ' hours,
style: const TextStyle(
fontSize: 20
)
),
],
),
),
),
);
}
I'm not sure if class object initialization works correct here, maybe you also need to add async/await
CodePudding user response:
class CanteenInfo {
final String canteenUrl = 'https://sigarra.up.pt/feup/pt/mob_eme_geral.cantinas';
List canteenMenu = [];
var data;
String workingHours = "yes";
getWebsiteData() async {
var response = await http.get(Uri.parse(canteenUrl));
if (response.statusCode == 200) {
data = json.decode(response.body);
workingHours = data[3]["horario"];
print("Hours: " workingHours);
}
else {
throw Exception('Failed to read $canteenUrl');
}
}
getHours() {
return workingHours;
}
}
// ------------------------
class WorkingHours extends StatefulWidget {
const WorkingHours({Key? key}) : super(key: key);
@override
State<WorkingHours> createState() => _WorkingHours();
}
// ------------------------
class _WorkingHours extends State<WorkingHours> {
String hours = "yes";
CanteenInfo canteen = CanteenInfo();
@override
void initState() {
super.initState();
canteen.getWebsiteData().then(() {
hours = canteen.getHours();
});
}
}