Food Ordering System Part 30 | Fixing the Cart Count Badge in ASP.NET Core MVC

 


In Part 30 of our Food Ordering System, we are addressing a common issue: ensuring the cart button accurately reflects the number of items a user has selected. This snippet ensures the frontend can fetch the current count asynchronously without a full page reload.


Code Explanation: Step-by-Step

The GetCartCount action is designed to be called via AJAX (typically from your JavaScript/jQuery layout file) to update the cart badge dynamically.

  1. [HttpGet] Attribute: This tells the controller that the method should only respond to HTTP GET requests. Since we are simply "getting" data and not changing the state of the server, a GET request is the correct semantic choice.

  2. HttpContext.Session.GetString("Cart"): In ASP.NET Core, session data is stored as a string (usually JSON). Here, we attempt to retrieve the string stored under the key "Cart".

  3. The Null/Empty Check:

    • If the session is empty (user hasn't added anything), the code skips the logic and keeps the count at 0.

    • This prevents "Null Reference" errors.

  4. JsonConvert.DeserializeObject<List<CartItem>>(cartJson): Since the cart is stored as a JSON string, we must convert it back into a C# List of CartItem objects so we can perform math on it.

  5. cart.Sum(c => c.Quantity): Instead of just counting the number of rows in the list, we sum up the Quantity of each item. (e.g., if you have 2 Pizzas and 1 Coke, the count should show 3, not 2).

  6. return Json(new { count }): The result is returned as a JSON object: { "count": X }. This makes it easy for your JavaScript to read data.count.


OrderController.cs
[HttpGet]
public IActionResult GetCartCount()
{
    // Retrieve the Cart JSON string from the Session
    var cartJson = HttpContext.Session.GetString("Cart");
    var count = 0;

    // Check if the cart is not empty
    if (!string.IsNullOrEmpty(cartJson))
    {
        // Deserialize the JSON back into a List of CartItems
        var cart = JsonConvert.DeserializeObject<List<CartItem>>(cartJson);
        
        // Sum up the total quantity of all items in the cart
        count = cart.Sum(c => c.Quantity);
    }

    // Return the count as a JSON object for AJAX calls
    return Json(new { count });
}

This JavaScript code is the "bridge" that connects your frontend UI to the backend logic we just created. It ensures that whenever a user loads a page, the cart number is fetched and displayed immediately.


Code Explanation: Step-by-Step

  1. document.addEventListener('DOMContentLoaded', ...): This is a safety measure. It tells the browser: "Wait until the entire HTML page is loaded before running this script." This prevents errors where the script tries to update the cartCount element before it actually exists on the screen.

  2. fetch('/Order/GetCartCount'): This uses the modern JavaScript Fetch API to send a background request to your controller. It hits the exact action we created in the previous step. Note: If your controller is named CartController, you would change this URL to /Cart/GetCartCount.

  3. .then(r => r.json()): The server sends back a raw response. This line converts that raw data into a readable JSON object.

  4. .then(d => { ... }): Here, d represents our data (the { count: X } object).

    • document.getElementById('cartCount'): Finds the HTML element (like a <span> or <i>) where the number should live.

    • .innerText = d.count: Injects the actual number into that element.



_Layout.cshtml (Scripts Section)
<script>
    document.addEventListener('DOMContentLoaded', function() {
        // Run update on page load
        updateCartCount();
    });

    function updateCartCount() {
        // AJAX fetch request to the Controller
        fetch('/Order/GetCartCount')
            .then(r => r.json())
            .then(d => {
                // Update the badge element with the new count
                document.getElementById('cartCount').innerText = d.count;
            });
    }
</script>

Comments