shotmeinthehead
shotmeinthehead

Reputation: 1291

Fetch data from internet with flutter but failed to show data

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

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

Answers (2)

Ravindra S. Patil
Ravindra S. Patil

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.

Result Image.

Full code

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

Yusuf
Yusuf

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

Related Questions