Search code examples
c#htmlrazorasp.net-core-mvcasp.net-core-viewcomponent

Auto update ViewComponent on view


I currently have this on my view:

Cart

But whenever I add something to the cart, it won't auto-update the count. Only whenever I refresh the page.

How can I make it so it auto-updates? It is with a View Component on the _Layout view.

CartViewComponent

public class CartViewComponent : ViewComponent
    {
        private readonly ApplicationDbContext _context;
        private readonly SignInManager<UserModel> _signInManager;
        private readonly UserManager<UserModel> _userManager;

        public CartViewComponent(
            ApplicationDbContext context, 
            SignInManager<UserModel> signInManager, 
            UserManager<UserModel> userManager)
        {
            _context = context;
            _signInManager = signInManager;
            _userManager = userManager;
        }

        public int CheckIfOrderExists()
        {
            var userId = Request.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);

            OrderMain orderMain = _context.OrderMains.Where(o => o.user_id == userId).FirstOrDefault();
            if (orderMain != null)
            {
                return orderMain.id;
            }
            else
            {
                return 0;
            }

        }

        public int CountItemsInShoppingCart(int order_id)
        {
            var result = (from orderlines in _context.OrderLines
                          join items in _context.Items on orderlines.item_id equals items.id
                          join ordermains in _context.OrderMains on orderlines.order_id equals ordermains.id
                          where orderlines.order_id == order_id
                          select orderlines).Count();

            return result;
        }

        public IViewComponentResult Invoke()
        {
            int order_id = CheckIfOrderExists();
            int count = CountItemsInShoppingCart(order_id);
            ViewBag.count = count;

            return View(ViewBag.count);
        }
    }

Default.cshtml

<span class="badge">@ViewBag.count</span>

_Layout.cshtml

...
<li>
    <a asp-area="" asp-controller="ShoppingCart" asp-action="Index">
        <span style="color:black;" class="glyphicon glyphicon-shopping-cart"></span>
        @await Component.InvokeAsync("Cart")
    </a>
</li>
...

Solution

  • I actually did it with a jQuery get function, instead of with View Components. In the get function I retrieve the public int TotalCount() from my ShoppingCartController.

    On the _Layout partial view I created the jQuery script, one for rendering the current value and one for updating the value every 2 seconds:

    <script src="~/lib/jquery/dist/jquery.min.js">
    </script>
    <!-- rendering the current value -->
    <script>
        $.get('/ShoppingCart/TotalCount', function (data) {
            $('#countCart').html(data);
        });
    </script>
    <!-- reloading the value every 2 seconds -->
    <script>
        setInterval(function () {
            $('#countCart').load('/ShoppingCart/TotalCount');
        }, 2000)
    </script>
    

    And the badge is also on the _Layout partial view:

    <span class="badge" id="countCart"></span>