skip to Main Content

This the provider details I am having

//is_products_changed_provider.dart


import 'package:flutter/material.dart';

class IsProductChangedProvider extends ChangeNotifier {
  bool isTheProductChanged = true;

  void changeIsTheProductChanged() {
    isTheProductChanged = !isTheProductChanged;
    notifyListeners();
  }
}

Now I want to use it in the products page, i.e. If products changed then only fetch data.

// products.dart

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wineasy/components/error_card.dart';
import 'package:wineasy/components/side_nav_bar.dart';
import 'package:wineasy/components/single_product_card.dart';
import 'package:wineasy/models/product_model.dart';

class Products extends StatefulWidget {
  const Products({Key? key}) : super(key: key);

  @override
  State<Products> createState() => _ProductsState();
}

class _ProductsState extends State<Products> {
  // initializing variable to get products from backend
  late Future<List<ProductModel>> futureProducts;

  @override
  void initState() {
    super.initState();

    //calling fetchProductData fucntion to store values that we got from backend
    futureProducts = fetchProductData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: const SideNavBar(),
      appBar: AppBar(
        backgroundColor: Colors.transparent,
      ),
      body: Consumer(builder: (context, isProductChangedProviderModel, child) {
        return FutureBuilder(
          //future builder for loading state
          future: futureProducts,
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              // Loading state
              return const Center(
                child: Padding(
                  padding: EdgeInsets.symmetric(horizontal: 30.0),
                  child: LinearProgressIndicator(),
                ),
              );
            } else if (snapshot.hasError) {
              // Error state
              return const Center(
                child: ErrorCard(errorText: "Failed to load data"),
              );
            } else {
              // Data loaded successfully
              List<ProductModel> productsList =
                  snapshot.data as List<ProductModel>;

              return Padding(
                padding: const EdgeInsets.symmetric(horizontal: 15.0),
                child: GridView.builder(
                  gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                      maxCrossAxisExtent:
                          320, // Set the number of columns in the grid
                      crossAxisSpacing: 15.0, // Set the spacing between columns
                      mainAxisSpacing: 15.0,
                      mainAxisExtent: 308 // Set the spacing between rows
                      ),
                  itemCount: productsList.length,
                  itemBuilder: (context, index) {
                    return SingleProductCard(
                      productName: productsList[index].productName,
                      productPrice: productsList[index].price,
                      productType: productsList[index].typeOfProduct,
                      productCategory: productsList[index].categoryOfProduct,
                      productDescription: productsList[index].description,
                      imageFile: productsList[index].imageFile,
                      productId: productsList[index].productId,
                      isAvailable: productsList[index].isAvailable,
                    );
                  },
                ),
              );
            }
          },
        );
      }),
    );
  }

  Future<List<ProductModel>> fetchProductData() async {
    const String getProductsUrl = "http://localhost:4848/api/product-list";

    try {
      Response serverResponse = await Dio().get(getProductsUrl);

      List<ProductModel> productsList = (serverResponse.data as List<dynamic>)
          .map((productData) => ProductModel.fromJson(productData))
          .toList();

      return productsList;
    } catch (e) {
      print('Error fetching data: $e');
      rethrow;
    }
  }
}

But I cannot implement this.
Help me with this

I was expecting that the fetchProductData() will only be called if the value of isTheProductChanged is true and after fetching make it false;

2

Answers


  1. You can put this line in your initState

    context.read<IsProductChangedProvider>().changeIsTheProductChanged();
    

    With this line you can call changeIsTheProductChangedmethod from your initState
    and if you want to access variable you can use

    context.watch<IsProductChangedProvider>(). isTheProductChanged;
    
    Login or Signup to reply.
  2. do this in your initstate

    SchedulerBinding.instance.addPostFrameCallback((_) {
      bool isProductChanged = Provider.of<IsProductChangedProvider>(context, listen: false).isTheProductChanged;
      if (isProductChanged) {
        futureProducts = fetchProductData();
      }
    });
    

    and to make it false after fetching, do this in your fetchProductData() when data is fetched

    Provider.of<IsProductChangedProvider>(context, listen: false).changeIsTheProductChanged();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search