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
You can put this line in your
initState
With this line you can call
changeIsTheProductChangedmethod
from yourinitState
and if you want to access variable you can use
do this in your initstate
and to make it false after fetching, do this in your
fetchProductData()
when data is fetched