Riverpod FutureProvider keeps on firiging again and again

607

{} != {}. Because of .family, you are creating a completely new provider every time you call watch(ephemerisFutureProvider({})). To select a previously-built provider via family, you must pass an identical value. And {} is never identical to {}, guaranteed. :)

Share:
607
Vishal Singh
Author by

Vishal Singh

Updated on December 30, 2022

Comments

  • Vishal Singh
    Vishal Singh over 1 year

    I am using Riverpod's FutureProvider with family. The FutureProvider keeps on running again and again. It shows the loading dialog only. Also the hot reload stops working. FutureProvider is working fine without family. Please help in finding what's wrong.

    enter image description here

    final ephemerisProvider =
        Provider((ref) => ApiService("https://localhost"));
    
    final ephemerisFutureProvider = FutureProvider.family
        .autoDispose<EpheModel, Map<String, dynamic>>((ref, data) async {
      var response = await ref.read(ephemerisProvider).getData(data);
      print(EpheModel.fromJSON(response));
      return EpheModel.fromJSON(response);
    });
    
    class Kundlis extends ConsumerWidget {
      static const routeName = "/kundlis";
      @override
      Widget build(BuildContext context, ScopedReader watch) {
        final AsyncValue<EpheModel> kundlis = watch(ephemerisFutureProvider({}));
        return Scaffold(
            appBar: AppBar(
              title: Text("Kundlis"),
            ),
            drawer: AppDrawer(),
            body: kundlis.when(
                data: (kundli) => Center(child: Text(kundli.toString())),
                loading: () => ProgressDialog(message: "Fetching Details..."),
                error: (message, st) =>
                    CustomSnackBar.buildErrorSnackbar(context, '$message')));
      }
    }
    
    class ApiService {
      final String url;
      ApiService(this.url);
      Future<Map<String, dynamic>> getData(Map<String, dynamic> data) async {
        try {
          http.Response response = await http.post(url + "/ephe",
              headers: <String, String>{'Content-Type': 'application/json'},
              body: jsonEncode(data));
          if (response.statusCode == 200) {
            return data;
          } else {
            throw Exception("Error Fetching Details");
          }
        } on SocketException {
          throw Exception("No Internet Connection");
        } on HttpException {
          throw Exception("Error Fetching Details");
        }
      }
    }
    
    • Alex Hartford
      Alex Hartford almost 3 years
      Note: don't use ref.read inside a provider. Prefer ref.watch.
    • Vishal Singh
      Vishal Singh almost 3 years
      @alexhartford I was using ref.watch. Same error was happening. Just changed the watch to read after watching a YouTube tutorial of ResoCoder. It didn't work either.
  • Vishal Singh
    Vishal Singh almost 3 years
    Thank you. This was the case. But then how can I pass map value in family?
  • Randal Schwartz
    Randal Schwartz almost 3 years
    It would have to be a const. So had you said const empty = {}; and used empty each time, those would have been identical.
  • Alexa289
    Alexa289 about 2 years
    @RandalSchwartz hi Randal, could you please help me on this one? it seems similar but I couldn't figure out the soulution stackoverflow.com/questions/71659721/…