so im new to flutter dart.. i want to retrieve data base on the user input code
the data will be display in a popup widget
i dont see any errors but the data does not show up
`void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: busNearby(),
);
}
}
class busNearby extends StatefulWidget {
const busNearby({super.key});
@override
_busNearbyState createState() => _busNearbyState();
}
class _busNearbyState extends State<busNearby> {
final TextEditingController queryController = TextEditingController();//retrieve user input n use in query
List<Map<String, dynamic>> dataList = [];
String dummy = '1086';
late BuildContext scaffoldContext;
//rest api
Future<void> fetchData(String query) async {
final response = await http.get(
Uri.parse(('https://laravelsyd-fypfinalver.herokuapp.com/getBusService?query=$query'))); //link
if (response.statusCode == 200) {
final List<dynamic> data = json.decode(response.body);
dataList = List<Map<String, dynamic>>.from(data);
} else {
throw Exception('Failed to load data');
}
}
void showFetchedData() {
showModalBottomSheet(
context: scaffoldContext,
builder: (BuildContext context) {
return Container(
child: ListView.builder(
itemCount: dataList.length,
itemBuilder: (context, index) {
final item = dataList[index];
return ListTile(
title: Text('Service: ${item['service']}'),
subtitle: Text('Next Bus: ${item['next bus']}'),
);
},
),
);
},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Data Retrieval Example'),
),
body: Center(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
controller: queryController,
decoration: const InputDecoration(
labelText: 'Enter Bus Service Code',
),
),
),
Builder(
builder: (context) {
scaffoldContext = context;
return ElevatedButton(
onPressed: () {
fetchData(queryController.text);
showFetchedData(); // Call this method after data is fetched
},
child: const Text('Fetch Data'),
);
},
),
if (dataList.isNotEmpty)//display data in a sizedbox
SizedBox(
width: 200,
height: 100,
child: ListView.builder(
itemCount: dataList.length,
itemBuilder: (context, index) {
final item = dataList[index];
return ListTile(
title: Text('Service: ${item['service']}'),
subtitle: Text('Next Bus: ${item['next bus']}'),
);
},
),
),
// area code
DataTable(
columns: const <DataColumn>[
DataColumn(label: Text('Service Code')),
DataColumn(label: Text('Location')),
],
rows: const <DataRow>[
DataRow(cells: <DataCell>[
DataCell(Text('1076')),
DataCell(Text('Larkin Terminal')),
]),
DataRow(cells: <DataCell>[
DataCell(Text('1084')),
DataCell(Text('Taman Universiti')),
]),
DataRow(cells: <DataCell>[
DataCell(Text('1019')),
DataCell(Text('Skudai Prade')),
]),
DataRow(cells: <DataCell>[
DataCell(Text('1052')),
DataCell(Text('Opposite Skudai Prade')),
]),
],
),
],
),
),
);
}`
i have try error checking but theres no error that are displayed
the only problem is that the data wont show
it will show the currently available bus service in the area code which will be insert by the user
if i try in the website it does have data
2
Answers
You completely ignored the fact that
fetchData
returns aFuture<>
, which means it works asyncronously. So your "Call this after" isn’t actually called after. It’s called as soon as it started.At least you need to do it like this:
Better would be to read and understand What is a Future and how do I use it?, because this will not be the only situation where you will run into problems.
async/await not considered. Can do the followings:
Or,