Introduction
In the last article, we learned how to implement event callbacks. There are times when we need to send some data with those events as well.
I highly recommend going through the last article which will help you to grasp the knowledge for this example.
The following is the 5 step approach, this 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
5 Steps
- Child component has a button which fires an event on its "onclick" event.
- "onclick" event has an event-handler "ProductSelected" which takes event arguments "MouseEventArgs and string", string variable stores the data that we are going to pass to parent component.
- "OnProductSelected" is a type of EventCallback which is an event handler delegate responsible for calling the "InvokeAsync" method which dispatches an event notification to the target component.
- At this step 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: "OnProductSelected" is a [Parameter] that we have exposed in a child class. (Refer step 3)
- Now the last step is to create a method in the parent component that we have bound in step 4's "OnProductSelected".
- You can use this method to implement your logic in the parent component, our method is "SelectedProductUpdate" which has a string parameter to accept the data from child component. (refer step 2)
The Blazor App
Let's create a blazor application to demonstrate this feature.
Following is the snapshot of the application, you would notice that our app has a single parent and has 2 children. I have highlighted 2 fields, each child has a button which triggers the event and sends the name of the phone to the parent component, and the parent is displaying that name in the UI.
In the following image, the Selected Product is displaying "iPhone 12" as I have clicked the left child's "Send Name" button.
Figure 2: iPhone 12 is clicked
In image 3, the Selected Product is displaying "iPhone 13" as I have clicked the button from the right child.
Figure 3: iPhone 13 is clicked
Step 1: Triggering source, a Button
<input type="button"
@onclick="(args)=> ProductSelected(args, SmartPhone.SmartPhoneName)"
value="Send Name: @SmartPhone.SmartPhoneName"/>
Listing 1: Button
As you would notice in the above code snippet, we have an event handler "ProductSelected" bound to onclick event. We need to implement this method.
Step 2: Event handler: ProductSelected
Here we are implementing that method but inside the body of this method we need the event callback OnProductSelected
private async Task ProductSelected(MouseEventArgs e, string name)
{
await OnProductSelected.InvokeAsync(name);
}
Listing 2: ProductSelected
Step 3: Parameter: OnProductSelected
We need a parameter through which the parent component can trigger the child component.
[Parameter]
public EventCallback<string> OnProductSelected { 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>
<h4 class="m-2" style="color:#051367;">@SmartPhone.SmartPhoneName </h4>
@foreach (var feature in SmartPhone.SmartPhoneFeatures)
{
<p class="m-1" style="color:#8E0505;">@feature.Specification - @feature.Value</p>
}
<input type="button" class="btn btn-success m-1" @onclick="(args)=> ProductSelected(args, SmartPhone.SmartPhoneName)" style="width:200px;" value="Send Name: @SmartPhone.SmartPhoneName"/>
</div>
@code {
[Parameter]
public SmartPhone SmartPhone { get; set; }
[Parameter]
public EventCallback<string> OnProductSelected { get; set; }
private async Task ProductSelected(MouseEventArgs e, string name)
{
await OnProductSelected.InvokeAsync(name);
}
}
Listing 4: Child.razor
2. 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
OnProductSelected="SelectedProductUpdate"/>
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 showing the name of the child component in the parent component, triggered by a button click from the child component. We are passing the name of the control from the child component to the parent component, and for that we need a method which has one string parameter to hold the passed value.
protected void SelectedProductUpdate(string productName)
{
SelectedProductName = productName;
}
Listing 6: Parent component's executable 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 SelectedProductUpdate, and binding it in the UI.
@page "/parent"
<style>
body {
background-color: #142F43;
}
</style>
<h3 class="text-primary">Parent</h3>
<p style="color:#71DFE7;">Selected Product: @SelectedProductName</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
OnProductSelected="SelectedProductUpdate"/>
}
</div>
</div>
@code {
List<SmartPhone> SmartPhones = new();
private string SelectedProductName { get; set; } = "";
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 SelectedProductUpdate(string productName)
{
SelectedProductName = productName;
}
}
Listing 7: Parent.razor
Summary
In this article, we learned what are the steps you need to take to send a parameter in event callbacks in blazor, we demonstrated the same with a Blazor server app.
In the next article, we are going to learn RenderFragment in Blazor, so stay tuned.
Note: Source code is attached for your reference, Happy coding!!