I am Calling an api when item is added to cart and if its success the snackbar will show for success but what if user added one after one too many products then the all snackbars will show one by one for long time so i want when user stops then snackbar should show only once the last one the latest one with msg MyCart Api
Timer? debounceSnackBarTimer;
Future<void> addToCart(Package package) async {
final prefs = await SharedPreferences.getInstance();
final accessToken = prefs.getString('accessToken');
final String apiUrl = await AppNetworkingUrls.addtoCart;
if (accessToken == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Please log in to add items to the cart',
style: GoogleFonts.poppins(),
),
),
);
return;
}
final url = Uri.parse(apiUrl);
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
};
final body = jsonEncode({
'quantity': 1,
'productId': product.id,
'packageId': package.id,
});
debounceSnackBarTimer?.cancel();
debounceSnackBarTimer = Timer(Duration(milliseconds: 800), () async {
try {
final response = await http.post(
url,
headers: headers,
body: body,
);
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
print(response.body);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: AppColors.buttonColor,
duration: Duration(seconds: 2),
content: Text(
responseData['message'] ?? 'Item added to cart',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
final cartProvider = Provider.of<Cart>(context, listen: false);
await cartProvider.fetchCartItems();
} else {
final responseData = jsonDecode(response.body);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
content: Text(
responseData['message'] ?? 'Failed to add item',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
}
} catch (error) {
print('Error adding to cart: $error');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
content: Text(
'Something went wrong. Please try again.',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
}
});
}
there is Diff products and every products have diff packages the user will add multiple products also but i want to show the latest once only
I have also tried the Debounce but its not working as i wanted please if anyone can help me in this debounce is working only if the user adds same products same package again and again then this works but i want it should work in all products and packages
I am Calling an api when item is added to cart and if its success the snackbar will show for success but what if user added one after one too many products then the all snackbars will show one by one for long time so i want when user stops then snackbar should show only once the last one the latest one with msg MyCart Api
Timer? debounceSnackBarTimer;
Future<void> addToCart(Package package) async {
final prefs = await SharedPreferences.getInstance();
final accessToken = prefs.getString('accessToken');
final String apiUrl = await AppNetworkingUrls.addtoCart;
if (accessToken == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Please log in to add items to the cart',
style: GoogleFonts.poppins(),
),
),
);
return;
}
final url = Uri.parse(apiUrl);
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
};
final body = jsonEncode({
'quantity': 1,
'productId': product.id,
'packageId': package.id,
});
debounceSnackBarTimer?.cancel();
debounceSnackBarTimer = Timer(Duration(milliseconds: 800), () async {
try {
final response = await http.post(
url,
headers: headers,
body: body,
);
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
print(response.body);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: AppColors.buttonColor,
duration: Duration(seconds: 2),
content: Text(
responseData['message'] ?? 'Item added to cart',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
final cartProvider = Provider.of<Cart>(context, listen: false);
await cartProvider.fetchCartItems();
} else {
final responseData = jsonDecode(response.body);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
content: Text(
responseData['message'] ?? 'Failed to add item',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
}
} catch (error) {
print('Error adding to cart: $error');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: Colors.red,
duration: Duration(seconds: 2),
content: Text(
'Something went wrong. Please try again.',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
}
});
}
there is Diff products and every products have diff packages the user will add multiple products also but i want to show the latest once only
I have also tried the Debounce but its not working as i wanted please if anyone can help me in this debounce is working only if the user adds same products same package again and again then this works but i want it should work in all products and packages
Share Improve this question asked 2 days ago Tanu PurohitTanu Purohit 1 1- You can use debouncer.Have a look at this article to get better idea about it. – Safal Shrestha Commented 2 days ago
2 Answers
Reset to default 2Call your API immediately and save the latest message, then use a debounce timer to display the Snackbar only once.
Timer? debounceSnackBarTimer;
String? latestMessage;
bool? latestApiCallSuccess;
Future<void> addToCart(Package package) async {
final prefs = await SharedPreferences.getInstance();
final accessToken = prefs.getString('accessToken');
final String apiUrl = await AppNetworkingUrls.addtoCart;
if (accessToken == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Please log in to add items to the cart',
style: GoogleFonts.poppins(),
),
),
);
return;
}
final url = Uri.parse(apiUrl);
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
};
final body = jsonEncode({
'quantity': 1,
'productId': product.id,
'packageId': package.id,
});
try {
final response = await http.post(url, headers: headers, body: body);
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
latestMessage =
responseData['message'] ?? 'Item added to cart';
latestApiCallSuccess = true;
final cartProvider = Provider.of<Cart>(context, listen: false);
await cartProvider.fetchCartItems();
} else {
final responseData = jsonDecode(response.body);
latestMessage =
responseData['message'] ?? 'Failed to add item';
latestApiCallSuccess = false;
}
} catch (error) {
latestMessage =
'Something went wrong. Please try again.';
latestApiCallSuccess = false;
}
// Debounce the display of the snackbar:
debounceSnackBarTimer?.cancel();
debounceSnackBarTimer = Timer(Duration(milliseconds: 800), () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: latestApiCallSuccess == true
? AppColors.buttonColor
: Colors.red,
duration: Duration(seconds: 2),
content: Text(
latestMessage ?? '',
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
});
}
You are almost correct by using Timer for a debouncer, the issue is occurring because the debounceSnackBarTimer
is reset every time a product is added.
You can try by giving delay of 800ms which will help you to pause for few millisecond before adding the new item so the snackbar will display once when the item is added, also set the value of latestSnackBarMessage
as null
. Try this if it helps.
Timer? debounceSnackBarTimer;
String? latestSnackBarMessage;
Future<void> addToCart(Package package) async {
final prefs = await SharedPreferences.getInstance();
final accessToken = prefs.getString('accessToken');
final String apiUrl = await AppNetworkingUrls.addtoCart;
if (accessToken == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'Please log in to add items to the cart',
style: GoogleFonts.poppins(),
),
),
);
return;
}
final url = Uri.parse(apiUrl);
final headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken',
};
final body = jsonEncode({
'quantity': 1,
'productId': product.id,
'packageId': package.id,
});
try {
final response = await http.post(
url,
headers: headers,
body: body,
);
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
latestSnackBarMessage = responseData['message'] ?? 'Item added to cart';
final cartProvider = Provider.of<Cart>(context, listen: false);
await cartProvider.fetchCartItems();
} else {
final responseData = jsonDecode(response.body);
latestSnackBarMessage = responseData['message'] ?? 'Failed to add item';
}
} catch (error) {
print('Error adding to cart: $error');
latestSnackBarMessage = 'Something went wrong. Please try again.';
}
debounceSnackBarTimer?.cancel();
debounceSnackBarTimer = Timer(Duration(milliseconds: 800), () {
if (latestSnackBarMessage != null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
behavior: SnackBarBehavior.floating,
backgroundColor: AppColors.buttonColor,
duration: Duration(seconds: 2),
content: Text(
latestSnackBarMessage!,
style: GoogleFonts.poppins(fontWeight: FontWeight.w500),
),
),
);
latestSnackBarMessage = null;
}
});
}