Reputation: 1291
I tried following the flutter doc from
text
but failed to show the data,
I suspect the problem is in the futureBuilder, haven't implement try-catch yet as I'm not sure what to call. Also when I use late Future futurePrayer;
at the class declaration level, the data show but with call error. but if I use late Future<Prayer> futurePrayer;
with class type annotation the error dissapear but not show the data
error image :
error image is just for showing data example
code : builder function
FutureBuilder(
future: futurePrayer,
builder: (context, snapshot) {
if (snapshot.hasData) {
// TODO: fix NoSuchMethodError: 'call
// Dynamic call of object has no instance method 'call'.
return Text(snapshot.data.ashar());
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
// By default, show a loading spinner.
return const CircularProgressIndicator();
}
),
ApiBaseHelper / getter
Future<Prayer> ApiBaseHelper() async {
final response = await http
.get(Uri.parse('https://api.myquran.com/v2/sholat/jadwal/1420/2025-01-05'));
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return Prayer.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
await ApiBaseHelper().catchError(print);
throw Exception('Failed to load album');
}
}
Prayer data class
// this class is not used yet
class PrayerResponse {
List<String>? prayerTime;
PrayerResponse({
required this.prayerTime,
});
PrayerResponse.fromJson(Map<String, dynamic> json) {
prayerTime = json['data']['jadwal'];
}
}
class Prayer {
final int id;
final String lokasi;
final String daerah;
final String ashar;
Prayer(
{
required this.id,
required this.lokasi,
required this.daerah,
required this.ashar,
}
);
factory Prayer.fromJson(Map<String, dynamic> json) {
return Prayer(
id : json['data']['id'],
lokasi : json['data']['lokasi'],
daerah : json['data']['daerah'],
ashar : json['data']['jadwal']['ashar'],
);
}
}
Upvotes: 1
Views: 103
Reputation: 14885
Try below code convert your model json_to_dart.
Fetch data from the API Method
Future<ResponseModel> fetchData() async {
final response = await http.get(
Uri.parse('https://api.myquran.com/v2/sholat/jadwal/1420/2025-01-05'),
);
if (response.statusCode == 200) {
final Map<String, dynamic> result = json.decode(response.body);
return ResponseModel.fromJson(result); // Return a single ResponseModel
} else {
throw Exception('Failed to load data');
}
}
UI
FutureBuilder<ResponseModel>(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
if (!snapshot.hasData) {
return Center(child: Text('No data available'));
}
final response = snapshot.data!;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Lokasi: ${response.data.lokasi}',
),
Text(
'Daerah: ${response.data.daerah}',
),
Divider(),
Text(
'Tanggal: ${response.data.jadwal.tanggal}',
),
SizedBox(height: 10),
Text(
'Imsak: ${response.data.jadwal.imsak}',
),
Text(
'Subuh: ${response.data.jadwal.subuh}',
),
Text(
'Terbit: ${response.data.jadwal.terbit}',
),
Text(
'Dhuha: ${response.data.jadwal.dhuha}',
),
Text(
'Dzuhur: ${response.data.jadwal.dzuhur}',
),
Text(
'Ashar: ${response.data.jadwal.ashar}',
),
Text(
'Maghrib: ${response.data.jadwal.maghrib}',
),
Text(
'Isya: ${response.data.jadwal.isya}',
),
],
),
);
},
),
For more you can refer my answer here for getting data from internet.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class ResponseModel {
final bool status;
final Request request;
final Data data;
ResponseModel(
{required this.status, required this.request, required this.data});
factory ResponseModel.fromJson(Map<String, dynamic> json) {
return ResponseModel(
status: json['status'],
request: Request.fromJson(json['request']),
data: Data.fromJson(json['data']),
);
}
}
class Request {
final String path;
final String year;
final String month;
final String date;
Request(
{required this.path,
required this.year,
required this.month,
required this.date});
factory Request.fromJson(Map<String, dynamic> json) {
return Request(
path: json['path'],
year: json['year'],
month: json['month'],
date: json['date'],
);
}
}
class Data {
final int id;
final String lokasi;
final String daerah;
final Jadwal jadwal;
Data(
{required this.id,
required this.lokasi,
required this.daerah,
required this.jadwal});
factory Data.fromJson(Map<String, dynamic> json) {
return Data(
id: json['id'],
lokasi: json['lokasi'],
daerah: json['daerah'],
jadwal: Jadwal.fromJson(json['jadwal']),
);
}
}
class Jadwal {
final String tanggal;
final String imsak;
final String subuh;
final String terbit;
final String dhuha;
final String dzuhur;
final String ashar;
final String maghrib;
final String isya;
final String date;
Jadwal({
required this.tanggal,
required this.imsak,
required this.subuh,
required this.terbit,
required this.dhuha,
required this.dzuhur,
required this.ashar,
required this.maghrib,
required this.isya,
required this.date,
});
factory Jadwal.fromJson(Map<String, dynamic> json) {
return Jadwal(
tanggal: json['tanggal'],
imsak: json['imsak'],
subuh: json['subuh'],
terbit: json['terbit'],
dhuha: json['dhuha'],
dzuhur: json['dzuhur'],
ashar: json['ashar'],
maghrib: json['maghrib'],
isya: json['isya'],
date: json['date'],
);
}
}
// main method
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: SholatJadwalScreen(),
));
}
/// UI class
class SholatJadwalScreen extends StatelessWidget {
// Fetch data from the API
Future<ResponseModel> fetchData() async {
final response = await http.get(
Uri.parse('https://api.myquran.com/v2/sholat/jadwal/1420/2025-01-05'),
);
if (response.statusCode == 200) {
final Map<String, dynamic> result = json.decode(response.body);
return ResponseModel.fromJson(result); // Return a single ResponseModel
} else {
throw Exception('Failed to load data');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Sholat Jadwal')),
body: FutureBuilder<ResponseModel>(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
if (!snapshot.hasData) {
return Center(child: Text('No data available'));
}
final response = snapshot.data!;
return Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Lokasi: ${response.data.lokasi}',
),
Text(
'Daerah: ${response.data.daerah}',
),
Divider(),
Text(
'Tanggal: ${response.data.jadwal.tanggal}',
),
SizedBox(height: 10),
Text(
'Imsak: ${response.data.jadwal.imsak}',
),
Text(
'Subuh: ${response.data.jadwal.subuh}',
),
Text(
'Terbit: ${response.data.jadwal.terbit}',
),
Text(
'Dhuha: ${response.data.jadwal.dhuha}',
),
Text(
'Dzuhur: ${response.data.jadwal.dzuhur}',
),
Text(
'Ashar: ${response.data.jadwal.ashar}',
),
Text(
'Maghrib: ${response.data.jadwal.maghrib}',
),
Text(
'Isya: ${response.data.jadwal.isya}',
),
],
),
);
},
),
);
}
}
Upvotes: 1
Reputation: 366
When I examined your code in general, one thing caught my attention. You are using a function sign () on the data coming from the future. I think this may cause the problem. Also, using a try catch block when making a request to the API may be more helpful in finding the source of the error.
You can try these codes for solution.
FutureBuilder<Prayer>(
future: futurePrayer,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
return Text('Ashar Time: ${snapshot.data!.ashar}');
} else {
return const Text('No data available');
}
},
),
Future<Prayer> ApiBaseHelper() async {
try {
final response = await http.get(
Uri.parse('https://api.myquran.com/v2/sholat/jadwal/1420/2025-01-05'),
);
if (response.statusCode == 200) {
return Prayer.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
throw Exception('Failed to load prayer data');
}
} catch (e) {
throw Exception('Error fetching data: $e');
}
}
Upvotes: 1