FutureProvider does not return data to UI

Zahid Tekbaş

I'm new using Riverpod and its providers. I have 2 almost identical futureProviders but one of them does not return data to UI even though API returns data.

Here is UI part


class ProductDetailSimilarProductsWidget extends ConsumerWidget {
  const ProductDetailSimilarProductsWidget(this.product, {super.key});

  final ProductDetailModel product;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    var value = ref.watch(getSimilarProductsFutureProvider([product.Id, product.KategoriId]));
    return Container(
      height: MediaQuery.of(context).size.height * 0.5,
      width: MediaQuery.of(context).size.width,
      child: value.when(
        data: (data) {
          print("data length:${data.length}");
          return ListView.builder(
            itemCount: data.length,
            shrinkWrap: true,
            scrollDirection: Axis.horizontal,
            itemBuilder: (context, index) {
              return Padding(
                padding: EdgeInsets.only(left: AppTheme.mediumPadding, right: AppTheme.mediumPadding),
                child: ProductGridContainerWidget(product: data[index]),
              );
            },
          );
        },
        error: (err, trace) {
          return Text(err.toString());
        },
        loading: () => AppTheme.spinkit,
      ),
    );
  }
}

Here is futureProvider object


final getSimilarProductsFutureProvider = FutureProvider.family<List<Products>, List<dynamic>>((ref, value) async {
  var result = await ProductDetailData().getSimilarProducts(productId: value[0], categoryId: value[1]);
  print("result: ${result.length}");
  return result;
});

Finally, the method does API call

    var service = ApiService();
    var sharedPreferencesManager = SharedPreferencesManager();
    await sharedPreferencesManager.init();
    var langId = await sharedPreferencesManager.getLanguageId();
    var countryId = await sharedPreferencesManager.getCountryId();
    var result =
        await service.getRequest(subUrl: "${ApiRoutes.getSimilarProducts}?productId=$productId&langId=$langId&countryId=$countryId&categoryId=$categoryId");
    List<Products> products = [];
    var elements = json.decode(result.body);
    await Future.forEach(elements, (element) => products.add(Products.fromMap(element as Map<String, dynamic>)));
    return products;

Inside provider object, result.length variable prints 10 and it is expected. But inside the UI part, widget stucks on loading part and does not print data.length variable.

Is there something wrong in my codes? Also API works fine and successfully returns data.

Ruble

Your mistake is probably using the list as an argument for .family.

Ideally, the parameter should either be a primitive (bool/int/double/String), a constant (providers), or an immutable object that overrides == and hashCode.

Try using Records or create an immutable object with the two required fields.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related