Custom JavaScript function in Blazor

In this new post customJavaScript function inBlazor, I present how to create functions inC# in a Blazor page and integrate them with JavaScript. What I explain in this post, it is coming fro myChartJs component for Blazor: this component allows you to create nice graphs usingChartJs library.
Scenario
The ChartJs library allows the developers to customise the chart usingcallbacks and here developers can write their own JavaScript code. For example, if you want to customise theTooltip for each point, you can use theTooltip Callbacks
const chart = new Chart(ctx, { type: 'line', data: data, options: { plugins: { tooltip: { callbacks: { label: function(context) { let label = context.dataset.label || ''; if (label) { label += ': '; } if (context.parsed.y !== null) { label += new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(context.parsed.y); } return label; } } } } }});So, if you look at the lines 6-18, thecallbacks has a propertylabel and here we can write our JavaScript code. Then, when the graph renders thetooltip for a point, the library calls thecallbacks function and displays the label in the format you define. Here the screenshot for the code above.

Here, you can try yourself with thisCodepen. When you move the mouse over a point, the tooltip is displaying the custom label.
So, the problem is how to replicate the same functionalities in the Blazor component and allow developers to create their custom code.
Then, I was looking for an implementation where I can add in a Blazor page the JavaScript code and call it in some way (see my first post in theMicrosoft Learn). Nothing was working.
I couldn’t understand how to pass data and communicate among the JavaScript code, the Blazor component and the Blazor Page. Most of the people redirected me to the Microsoft Learn page called “Call JavaScript functions from .NET methods in ASP.NET Core Blazor” but wasn’t useful. After few months, a pull request onGitHub fromMacias opened my mind.
Anatomy of the component
First, just few words about the ChartJs component for Blazor and how it is working. Obviously this is an example to implement your custom JavaScript function in your Blazor components and projects.

So, I’m telling you all this stuff to explain my thoughts about the component. But also, how I discovered the correct implementation.
Chart.js script
First, theChart.js script is the core of all component. As I said, this is based on the javascript library ChartJs. So, the component is a faced of it adding the ability to use it in Blazor applications. So, this script calls and communicates with the ChartJs library to create the chart.
The component exposes the properties, methods and events to developers in their Blazor pages. The real definition of the settings are coming from the Blazor page. Then, the script initialises the chart calling the ChartJS library.
In this script, there are other functions available out-of-the-box, such as thecrosshair. Also, the component raises events and calls to the Blazor component. For example, when the user clicks on the chart, the Chart.js invokeChartClick in the Blazor component.
Blazor component
In order to create the chart, the script has to receives the configuration of the chart from the Blazor component. The component is simplified the creation exposing properties, events and methods that developers can use in their applications.
So, in same way I have to add here something that developers can use to add their code in C#.
Blazor page
Finally, this is the page where we want to generate the chart, passing to the component all the settings. Also, in here I want to add my custom code to change the chart.
What I need to do
So, focus on theTooltip callbacks, what I need is:
- the JavaScript has to call the Blazor component for a particular event (in this case when there is a callback during the creation of a tooltip)
- the Blazor component must to receive the call or connect the code between the JavaScript code and the custom code in the page
- the Blazor component must call the custom code, pass parameters if it needs them and sends back the result
Implementation in the component
Now, we know the structure of the component and what I want to do. So, we can start to analyse how to implement the solution. First, in the component I define
private DotNetObjectReference<IChartConfig>? dotNetObjectRef;
As the name says, this is a reference of my chart configuration that has all the data, labels and options. When theChart.js calls a function in this component, it will pass always this object to access the data and options.
Then, I have to define a function that Chart.js can call. For that, I have to define aJSInvokable function like that
[JSInvokable]public static string[] TooltipCallbacksLabel( DotNetObjectReference<IChartConfig> config, int[] parameters){ var ctx = new CallbackGenericContext(parameters[0], parameters[1]); if (config.Value.Options is Options options) return options.Plugins.Tooltip.Callbacks.Label(ctx); else throw new NotSupportedException();}So, what is it happing here? The magic Is here. TheChart.js callsTooltipCallbacksLabel with 2 parameters: the configuration of the chart and someparameters that in this particular case are the value of a specific point in the chart.
In theconfig, the component checks if theOptions are defined and if there is a particular implementation for theCallbacks.Label. If there is one, it pass the values to the function. Basically, this is how the Blazor component calls a custom C# code in the Blazor pageant return to theChart.js the result. In this case, the result of the C# is a string.
In the Blazor page
So, let me show you the implementation in the Blazor page.
protected override async Task OnInitializedAsync(){ _config1 = new BarChartConfig() { Options = new Options() { Responsive = true, MaintainAspectRatio = false, Plugins = new Plugins() { Legend = new Legend() { Align = Align.Center, Display = true, Position = LegendPosition.Right }, Tooltip = new Tooltip() { Callbacks = new Callbacks() { Label = (ctx) => { return new[] { $"DataIndex: {ctx.DataIndex}\nDatasetIndex: {ctx.DatasetIndex}" }; }, Title = (ctx) => { return new[] { $"This is the value {ctx.Value}" }; } } } }, Scales = new Dictionary<string, Axis>() { { Scales.XAxisId, new Axis() { Stacked = true, Ticks = new Ticks() { MaxRotation = 0, MinRotation = 0 } } }, { Scales.YAxisId, new Axis() { Stacked = true } } } } };Look at the lines between 17 and 30. Here is where the Blazor page receives from the Blazor component the values from theChart.js script. This code creates astring[] to change the text in the tooltip for a particular point. So, there is a constant communication between the Blazor component and the JavaScript underneath. When it is the code, the Blazor component pass the control to the Blazor page and then the result to the JavaScript.
In the JavaScript
And what is the code in theChart.js? In the configuration of the chart, I pass theDotNetObjectReference. When the ChartJs library wants to call thelabelcallbacks, there is a function that invoke theJSInvokable function I defined in the Blazor component. The call is using the namespace of the component (in this casePSC.Blazor.Components.Chartjs) and the function I want to call (in this caseTooltipCallbacksLabel).
config.options.plugins.tooltip.callbacks.label = function (ctx) { return DotNet.invokeMethod('PSC.Blazor.Components.Chartjs', 'TooltipCallbacksLabel', dotnetConfig, [ctx.datasetIndex, ctx.dataIndex]);};As parameters, the function pass to the Blazor component the chart configuration and an array with some values (in this casedatasetIndex anddataIndex available in this function). So, the Blazor component pass the parameters to the custom code in the Blazor page, receives the new string and pass the string to theChart.js that pass the value to the ChartJs library.
Wrap up
I took almost a year to understand how to create custom JavaScript function in a Blazor component that can communicate among them. I couldn’t find any documentation that explain how to do it. So, I hope this can help someone else.
For more info, you can visit:
- theGitHub repository for ChartJs component t for Blazor
- ChartJs Blazor component for Blazor post
- Labels and OnClickChart for ChartJs
- theforum for this component
- download theNuGet package
- play with the demo
Happy coding!
Related posts

New MarkdownEditor components for JavaScript and Blazor
Today, after 2 years, I released a new Markdown Editor components for JavaScript and Blazor. The...
Language In Use is here!
Language In Use is here! I'm so excited about the presentation of my new project. My...
NET8, Blazor and Custom User Management
I will show how to create custom user management with NET8 and Blazor based on Microsoft...
Leave a ReplyCancel reply
This site uses Akismet to reduce spam.Learn how your comment data is processed.




