Hello there.
Today we are going to learn how to send events from child to parent component in blazor. There are 5 precise steps that we need to follow.
I have created the diagram below which will help you to understand the flow of control from source to destination with respect to events in blazor.
Figure 1: Event Callback's flow of control
Alright, we are going to create a Blazor server app to have a live demonstration of event callbacks. Before that let's crack figure 1.
5 Steps
- Child component has checkbox which fires an event on its
onchange
event.
onchange
event has event handler FavouritePhoneUpdated
which takes event arguments ChangeEventArgs
.
OnFavouritePhoneSelection
is a type of EventCallback which is an event handler delegate responsbile for calling InvokeAsync method which dispatches an event notification to the target component.
- This is where we create an instance of a child component where we are passing a method which needs to be executed whenever an event is fired.
- Note:
OnFavouritePhoneSelection
is a [Parameter] that we have exposed in a child class.
- Now the last step is to create a method in the parent component that we have bound in step 4's
OnFavouritePhoneSelection
.
- You can use this method to implement your logic in parent component
The Blazor App
Let's create a blazor application to demonstrate it's working.
Following is the snapshot of the application, you would notice that is a single parent and has 2 children. I have highlighted 3 fields, each child has a checkbox to "add to favorite" checkbox, and the parent has a total number of favorite children.
In the following figure the count for favorite child is 0 as we have not selected any of the children.
Figure 2: None of the child is selected
In figure 3, we have selected both of the children and now parent favorite count has been updated to 2.
Figure 3: Both children are selected
Explanation
Each child sends an event to its parent on their checkbox's selection, and then parent retrieves that event and uses its own logic to increment or decrement the "favorite child" count.
Let's Jump into the coding
Go ahead and crank up visual studio and select "Blazor server app" as shown in figure 4.
Figure 4: Blazor Server App
Now we need to add 2 razor components.
- Child
- Parent
1. The Child Component
Figure 3: Right click on project and select Razor Component
Step 1 - Source of event: CheckBox
As per our architecture in figure 1, We begin with a control that throws an event. In this case, we have a checkbox so let's go ahead and add a checkbox in a child.razor page.
<input class="m-1" type="checkbox" @onchange="FavouritePhoneUpdated"/> Add to Favorite
Listing 1: Checkbox
As you would notice in above code snippet, we have an event handler FavouritePhoneUpdated
bound to onchange
event. we need to implement this method.
Step 2: Event handler: FavouritePhoneUpdated
Here we are implementing that method but inside a body of this method we need the event callback OnFavouritePhoneSelection
private async Task FavouritePhoneUpdated(ChangeEventArgs e)
{
await OnFavouritePhoneSelection.InvokeAsync((bool)e.Value);
}
Listing 2: FavouritePhoneUpdated
Step 3: Parameter: OnFavouritePhoneSelection
Before that we need a parameter through which the parent component can trigger the child component.
[Parameter]
public EventCallback<bool> OnFavouritePhoneSelection { get; set; }
Listing 3: EventCallback
Let me also give you the entire source code of the child component. There is a lot of noise in the below code snippet but all we need to understand is the above 3 steps.
<h3 style="color:#BFFFF0;">Child: @SmartPhone.Id </h3>
<div class="border m-2 col-5" style="background-color:#D1D1D1">
<h4 class="text-secondary m-1"> Smart Phone: @SmartPhone.Id </h4>
<input class="m-1" type="checkbox" @onchange="FavouritePhoneUpdated"/> Add to Favorite
<div class="m-1" style="color:#FF0000;">
Name: @SmartPhone.SmartPhoneName<br />
</div>
@foreach (var feature in SmartPhone.SmartPhoneFeatures)
{
<p class="m-1" style="color:#8E0505;">@feature.Specification - @feature.Value</p>
}
<br />
</div>
@code {
[Parameter]
public SmartPhone SmartPhone {
get;
set;
}
[Parameter]
public EventCallback < bool > OnFavouritePhoneSelection {
get;
set;
}
private async Task FavouritePhoneUpdated(ChangeEventArgs e) {
await OnFavouritePhoneSelection.InvokeAsync((bool) e.Value);
}
}
Listing 4: Child.razor
2. The Parent component
Figure 4: The parent component
Step 4: Instance of child component in a parent component
First thing first,
Parent contains a child component so we need to create a child component's instance inside a parent component.
When we create an instance, we can access the parameter from step 3.
<Child SmartPhone=@smartPhone OnFavouritePhoneSelection="FavouriteCountUpdate"/>
Listing 5: Child component's instance
Step 5: Your logic in the parent component.
The last is the triggered method, where your logic comes. In our example, we are increasing a count of a variable based on the number of child's checkboxes selection. So on select, we will increment the count and on deselect we will simply decrement the count.
protected void FavouriteCountUpdate(bool isSelected) {
if (isSelected) {
FavouritePhoneCount++;
} else {
FavouritePhoneCount--;
}
}
Listing 6: Parent component's method when event is triggered
To give you full disclosure, let me share the entire source code of the parent.razor file. We are using this variable FavouritePhoneCount
, and binding it in the UI.
@page "/parent"
<style>
body {
background-color: #142F43;
}
</style>
<h3 class="text-primary">Parent</h3>
<p style="color:#71DFE7;">Favourites Total: @FavouritePhoneCount</p>
<div class="border p-2 mt-2 " style="background-color:#203239">
<div class="d-flex p-2">
@foreach (SmartPhone smartPhone in SmartPhones)
{
<Child SmartPhone=@smartPhone OnFavouritePhoneSelection="FavouriteCountUpdate"/>
}
</div>
</div>
@code {
List < SmartPhone > SmartPhones = new();
private int FavouritePhoneCount {
get;
set;
} = 0;
protected override void OnInitialized() {
base.OnInitialized();
SmartPhones.Add(new() {
Id = 1,
SmartPhoneName = "iPhone 12",
IsAvailable = false,
Price = "$ 850",
SmartPhoneFeatures = new() {
new Feature {
Specification = "Chip", Value = "A14 Bionic chip"
},
new Feature {
Specification = "Display", Value = "Super Retina XDR display"
},
new Feature {
Specification = "Camera", Value = "Wide and Ultra Wide"
}
}
});
SmartPhones.Add(new() {
Id = 2,
SmartPhoneName = "iPhone 13",
IsAvailable = false,
Price = "$ 1050",
SmartPhoneFeatures = new() {
new Feature {
Specification = "Chip", Value = "A15 Bionic chip"
},
new Feature {
Specification = "Display", Value = "Super Retina XDR display"
},
new Feature {
Specification = "Camera", Value = "Telephoto, Wide and Ultra Wide"
}
}
});
}
protected void FavouriteCountUpdate(bool isSelected) {
if (isSelected) {
FavouritePhoneCount++;
} else {
FavouritePhoneCount--;
}
}
}
Listing 7: Parent.razor
Summary
In this article, we learned what are the steps you need to take to implement callback events in blazor, we demonstrated the same with a Blazor server app. In the next article, we will see how we can send parameters to these events.
Note: Source code is attached for your reference, Happy coding!!