Duy Lan Le
Duy Lan Le

Reputation: 298

How to re-render a component from another component in Blazor?

I have an Ecommerce Blazor Server project and I want to re-render the Cart component after adding a item to the Cart from a Product Component. I tried to inherits the Cart component to Product component and run a public method of Cart component to re-render its component.

The Add to cart method in Product Component.

Product.Razor

 public async Task AddToCart()
{
    //The adding logic in this area

    StateHasChanged();
    Reload(); // this method is inherited from the Cart Component trying to re-render the Cart Component
    //Does not work
}

Cart.Razor

[Parameter]
public List<Models.Cart> CartItem { get; set; }

protected override void OnInitialized()
{
    CartItem = _context.Cart.Where(i => i.CustomUserId == _userManager.GetUserId(_httpContextAccessor.HttpContext.User) && !i.IsSold).ToList();
}


public void Reload()
{

    OnInitialized();
    StateHasChanged();

}

The method run through successfully but the UI is not re-rendered like the way I want it to be.

I though the UI will re-render when I run the OnInitialized() method and StateHasChanged()?

Edit: I update my Reload() method and call that at the end of AddToCart() method but it doesn't work :(

Cart.Razor

 protected override void OnParametersSet()
{
    CartItem = _context.Cart.Where(i => i.CustomUserId == _userManager.GetUserId(_httpContextAccessor.HttpContext.User) && !i.IsSold).ToList();
}


public void Reload()
{
    OnParametersSet(); //updated but still not working
    StateHasChanged();

}

Product.Razor

public async Task AddToCart()
    {
        //The adding logic in this area

        Reload(); // this method is inherited from the Cart Component trying to re-render the Cart Component
        //Does not work
        StateHasChanged();
    }

Upvotes: 12

Views: 13022

Answers (1)

Neil W
Neil W

Reputation: 9247

Inheriting from Cart does not mean you are looking at the same instance as the 'other' cart in your project. You are inheriting the class (definition of) Cart, not the running component.

You have two ways to solve this:

Use a common parent component

  1. Put Product.razor and Cart.razor as child components of a common parent commponent.
  2. In Product.razor, after adding the item to the cart raise an event like OnItemAdded.
  3. Catch this event in the parent component
  4. From parent component call Reload() on the instance of the Cart Component that is running. (See @ref attribute for components - https://blazor-university.com/javascript-interop/calling-javascript-from-dotnet/passing-html-element-references/).

Use an event broadcaster

  1. Create an Event Broadcast Service (https://morioh.com/p/a5df9450ff5e)
  2. In Product.razor, after adding the item to the cart, broadcast a message.
  3. Listen for that message in Cart.razor
  4. Update the view in Cart.razor when that message is received

Upvotes: 12

Related Questions