androidiosflutterdartsnackbar

How to show Snackbar only once


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


Solution

  • Call 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),
            ),
          ),
        );
      });
    }