Skip to content

Commit 653d4b7

Browse files
committed
Refactor JS interop: add JsInteropBase, unify error handling
Introduce JsInteropBase to centralize JS module management and safe invocation for Blazor components. Refactor PdfViewerJsInterop, SortableListJsInterop, and ThemeSwitcherJsInterop to inherit from this base class, removing redundant DisposeAsync logic. Replace direct JSRuntime.InvokeVoidAsync calls with SafeInvokeVoidAsync across components (charts, Demo, Snippet, Toasts) to handle disconnects and cancellations gracefully. Remove unused JS property from Demo. Improves robustness and maintainability of JS interop throughout the codebase.
1 parent a10a6fd commit 653d4b7

File tree

16 files changed

+140
-178
lines changed

16 files changed

+140
-178
lines changed

BlazorBootstrap.Demo.RCL/Components/Shared/Demo.razor.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public partial class Demo : BlazorBootstrapComponentBase
2424
protected override async Task OnAfterRenderAsync(bool firstRender)
2525
{
2626
if (firstRender)
27-
await JS.InvokeVoidAsync("highlightCode");
27+
await SafeInvokeVoidAsync("highlightCode");
2828

2929
await base.OnAfterRenderAsync(firstRender);
3030
}
@@ -97,16 +97,14 @@ public void ResetCopyStatusJS()
9797
StateHasChanged();
9898
}
9999

100-
private async Task CopyToClipboardAsync() => await JS.InvokeVoidAsync("copyToClipboard", snippet, objRef);
100+
private async Task CopyToClipboardAsync() => await SafeInvokeVoidAsync("copyToClipboard", snippet, objRef);
101101

102102
#endregion
103103

104104
#region Properties, Indexers
105105

106106
protected override string? ClassNames => BuildClassNames(Class, ("bd-example-snippet bd-code-snippet", true));
107107

108-
[Inject] protected IJSRuntime JS { get; set; } = default!;
109-
110108
[Parameter] public LanguageCode LanguageCode { get; set; } = LanguageCode.Razor;
111109

112110
[Parameter] public bool ShowCodeOnly { get; set; }

BlazorBootstrap.Demo.RCL/Components/Shared/Snippet.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
namespace BlazorBootstrap.Demo.RCL;
22

3-
public class Snippet : ComponentBase
3+
public class Snippet : BlazorBootstrapComponentBase
44
{
55
#region Members
66

77
private string? snippet;
8+
private bool isJsRuntimeAvailable = true;
89

910
#endregion
1011

@@ -31,7 +32,7 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
3132
protected override async Task OnAfterRenderAsync(bool firstRender)
3233
{
3334
if (firstRender)
34-
await JS.InvokeVoidAsync("highlightCode");
35+
await SafeInvokeVoidAsync("highlightCode");
3536

3637
await base.OnAfterRenderAsync(firstRender);
3738
}
@@ -69,8 +70,6 @@ protected override async Task OnParametersSetAsync()
6970

7071
#region Properties
7172

72-
[Inject] protected IJSRuntime JS { get; set; } = null!;
73-
7473
[Parameter] public LanguageCode LanguageCode { get; set; } = LanguageCode.Razor;
7574

7675
[Parameter] public string? FilePath { get; set; }

blazorbootstrap/Components/Charts/BarChart.razor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
3535
if (data is BarChartDatasetData barChartDatasetData)
3636
barChartDataset.Data?.Add(barChartDatasetData.Data as double?);
3737

38-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
38+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
3939

4040
return chartData;
4141
}
@@ -80,7 +80,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
8080
barChartDataset.Data?.Add(barChartDatasetData.Data as double?);
8181
}
8282

83-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (BarChartDatasetData)x));
83+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (BarChartDatasetData)x));
8484

8585
return chartData;
8686
}
@@ -99,7 +99,7 @@ public override async Task<ChartData> AddDatasetAsync(ChartData chartData, IChar
9999
if (chartDataset is BarChartDataset)
100100
{
101101
chartData.Datasets.Add(chartDataset);
102-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, (BarChartDataset)chartDataset);
102+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDataset", Id, (BarChartDataset)chartDataset);
103103
}
104104

105105
return chartData;
@@ -111,7 +111,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch
111111
{
112112
var datasets = chartData.Datasets.OfType<BarChartDataset>();
113113
var data = new { chartData.Labels, Datasets = datasets };
114-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (BarChartOptions)chartOptions, plugins);
114+
await SafeInvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (BarChartOptions)chartOptions, plugins);
115115
}
116116
}
117117

@@ -121,7 +121,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO
121121
{
122122
var datasets = chartData.Datasets.OfType<BarChartDataset>();
123123
var data = new { chartData.Labels, Datasets = datasets };
124-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (BarChartOptions)chartOptions);
124+
await SafeInvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (BarChartOptions)chartOptions);
125125
}
126126
}
127127

blazorbootstrap/Components/Charts/BlazorBootstrapChart.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ public virtual async Task InitializeAsync(ChartData chartData, IChartOptions cha
4747
var _data = GetChartDataObject(chartData);
4848

4949
if (chartType == ChartType.Bar)
50-
await JSRuntime.InvokeVoidAsync("window.blazorChart.bar.initialize", Id, GetChartType(), _data, (BarChartOptions)chartOptions, plugins);
50+
await SafeInvokeVoidAsync("window.blazorChart.bar.initialize", Id, GetChartType(), _data, (BarChartOptions)chartOptions, plugins);
5151
else if (chartType == ChartType.Line)
52-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.initialize", Id, GetChartType(), _data, (LineChartOptions)chartOptions, plugins);
52+
await SafeInvokeVoidAsync("window.blazorChart.line.initialize", Id, GetChartType(), _data, (LineChartOptions)chartOptions, plugins);
5353
else
54-
await JSRuntime.InvokeVoidAsync("window.blazorChart.initialize", Id, GetChartType(), _data, chartOptions, plugins);
54+
await SafeInvokeVoidAsync("window.blazorChart.initialize", Id, GetChartType(), _data, chartOptions, plugins);
5555
}
5656
}
5757

@@ -70,7 +70,7 @@ public async Task ResizeAsync(int width, int height, Unit widthUnit = Unit.Px, U
7070
{
7171
var widthWithUnit = $"width:{width.ToString(CultureInfo.InvariantCulture)}{widthUnit.ToCssString()}";
7272
var heightWithUnit = $"height:{height.ToString(CultureInfo.InvariantCulture)}{heightUnit.ToCssString()}";
73-
await JSRuntime.InvokeVoidAsync("window.blazorChart.resize", Id, widthWithUnit, heightWithUnit);
73+
await SafeInvokeVoidAsync("window.blazorChart.resize", Id, widthWithUnit, heightWithUnit);
7474
}
7575

7676
/// <summary>
@@ -86,11 +86,11 @@ public virtual async Task UpdateAsync(ChartData chartData, IChartOptions chartOp
8686
var data = GetChartDataObject(chartData);
8787

8888
if (chartType == ChartType.Bar)
89-
await JSRuntime.InvokeVoidAsync("window.blazorChart.bar.update", Id, GetChartType(), data, (BarChartOptions)chartOptions);
89+
await SafeInvokeVoidAsync("window.blazorChart.bar.update", Id, GetChartType(), data, (BarChartOptions)chartOptions);
9090
else if (chartType == ChartType.Line)
91-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.update", Id, GetChartType(), data, (LineChartOptions)chartOptions);
91+
await SafeInvokeVoidAsync("window.blazorChart.line.update", Id, GetChartType(), data, (LineChartOptions)chartOptions);
9292
else
93-
await JSRuntime.InvokeVoidAsync("window.blazorChart.update", Id, GetChartType(), data, chartOptions);
93+
await SafeInvokeVoidAsync("window.blazorChart.update", Id, GetChartType(), data, chartOptions);
9494
}
9595
}
9696

@@ -106,11 +106,11 @@ public virtual async Task UpdateValuesAsync(ChartData chartData)
106106
var data = GetChartDataObject(chartData);
107107

108108
if (chartType == ChartType.Bar)
109-
await JSRuntime.InvokeVoidAsync("window.blazorChart.bar.updateDataValues", Id, data);
109+
await SafeInvokeVoidAsync("window.blazorChart.bar.updateDataValues", Id, data);
110110
else if (chartType == ChartType.Line)
111-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.updateDataValues", Id, data);
111+
await SafeInvokeVoidAsync("window.blazorChart.line.updateDataValues", Id, data);
112112
else
113-
await JSRuntime.InvokeVoidAsync("window.blazorChart.updateDataValues", Id, data);
113+
await SafeInvokeVoidAsync("window.blazorChart.updateDataValues", Id, data);
114114
}
115115
}
116116

blazorbootstrap/Components/Charts/DoughnutChart.razor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
3838
doughnutChartDataset.BackgroundColor?.Add(doughnutChartDatasetData.BackgroundColor!);
3939
}
4040

41-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
41+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
4242

4343
return chartData;
4444
}
@@ -86,7 +86,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
8686
}
8787
}
8888

89-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (DoughnutChartDatasetData)x));
89+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (DoughnutChartDatasetData)x));
9090

9191
return chartData;
9292
}
@@ -105,7 +105,7 @@ public override async Task<ChartData> AddDatasetAsync(ChartData chartData, IChar
105105
if (chartDataset is DoughnutChartDataset doughnutChartDataset)
106106
{
107107
chartData.Datasets.Add(doughnutChartDataset);
108-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, doughnutChartDataset);
108+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDataset", Id, doughnutChartDataset);
109109
}
110110

111111
return chartData;
@@ -117,7 +117,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch
117117
{
118118
var datasets = chartData.Datasets.OfType<DoughnutChartDataset>();
119119
var data = new { chartData.Labels, Datasets = datasets };
120-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (DoughnutChartOptions)chartOptions, plugins);
120+
await SafeInvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (DoughnutChartOptions)chartOptions, plugins);
121121
}
122122
}
123123

@@ -127,7 +127,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO
127127
{
128128
var datasets = chartData.Datasets.OfType<DoughnutChartDataset>();
129129
var data = new { chartData.Labels, Datasets = datasets };
130-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (DoughnutChartOptions)chartOptions);
130+
await SafeInvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (DoughnutChartOptions)chartOptions);
131131
}
132132
}
133133

blazorbootstrap/Components/Charts/LineChart.razor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
2929
if (data is LineChartDatasetData lineChartDatasetData)
3030
lineChartDataset.Data?.Add(lineChartDatasetData.Data as double?);
3131

32-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.addDatasetData", Id, dataLabel, data);
32+
await SafeInvokeVoidAsync("window.blazorChart.line.addDatasetData", Id, dataLabel, data);
3333

3434
return chartData;
3535
}
@@ -74,7 +74,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
7474
lineChartDataset.Data?.Add(lineChartDatasetData.Data as double?);
7575
}
7676

77-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.addDatasetsData", Id, dataLabel, data?.Select(x => (LineChartDatasetData)x));
77+
await SafeInvokeVoidAsync("window.blazorChart.line.addDatasetsData", Id, dataLabel, data?.Select(x => (LineChartDatasetData)x));
7878

7979
return chartData;
8080
}
@@ -93,7 +93,7 @@ public override async Task<ChartData> AddDatasetAsync(ChartData chartData, IChar
9393
if (chartDataset is LineChartDataset)
9494
{
9595
chartData.Datasets.Add(chartDataset);
96-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.addDataset", Id, (LineChartDataset)chartDataset);
96+
await SafeInvokeVoidAsync("window.blazorChart.line.addDataset", Id, (LineChartDataset)chartDataset);
9797
}
9898

9999
return chartData;
@@ -112,7 +112,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch
112112

113113
var datasets = chartData.Datasets.OfType<LineChartDataset>();
114114
var data = new { chartData.Labels, Datasets = datasets };
115-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.initialize", Id, GetChartType(), data, (LineChartOptions)chartOptions, plugins);
115+
await SafeInvokeVoidAsync("window.blazorChart.line.initialize", Id, GetChartType(), data, (LineChartOptions)chartOptions, plugins);
116116
}
117117

118118
public override async Task UpdateAsync(ChartData chartData, IChartOptions chartOptions)
@@ -128,7 +128,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO
128128

129129
var datasets = chartData.Datasets.OfType<LineChartDataset>();
130130
var data = new { chartData.Labels, Datasets = datasets };
131-
await JSRuntime.InvokeVoidAsync("window.blazorChart.line.update", Id, GetChartType(), data, (LineChartOptions)chartOptions);
131+
await SafeInvokeVoidAsync("window.blazorChart.line.update", Id, GetChartType(), data, (LineChartOptions)chartOptions);
132132
}
133133

134134
#endregion

blazorbootstrap/Components/Charts/PieChart.razor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
3838
pieChartDataset.BackgroundColor?.Add(pieChartDatasetData.BackgroundColor!);
3939
}
4040

41-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
41+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
4242

4343
return chartData;
4444
}
@@ -86,7 +86,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
8686
}
8787
}
8888

89-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (PieChartDatasetData)x));
89+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (PieChartDatasetData)x));
9090

9191
return chartData;
9292
}
@@ -105,7 +105,7 @@ public override async Task<ChartData> AddDatasetAsync(ChartData chartData, IChar
105105
if (chartDataset is PieChartDataset pieChartDataset)
106106
{
107107
chartData.Datasets.Add(pieChartDataset);
108-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, pieChartDataset);
108+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDataset", Id, pieChartDataset);
109109
}
110110

111111
return chartData;
@@ -117,7 +117,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch
117117
{
118118
var datasets = chartData.Datasets.OfType<PieChartDataset>();
119119
var data = new { chartData.Labels, Datasets = datasets };
120-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (PieChartOptions)chartOptions, plugins);
120+
await SafeInvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (PieChartOptions)chartOptions, plugins);
121121
}
122122
}
123123

@@ -127,7 +127,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO
127127
{
128128
var datasets = chartData.Datasets.OfType<PieChartDataset>();
129129
var data = new { chartData.Labels, Datasets = datasets };
130-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (PieChartOptions)chartOptions);
130+
await SafeInvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (PieChartOptions)chartOptions);
131131
}
132132
}
133133

blazorbootstrap/Components/Charts/PolarAreaChart.razor.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
3636
if (data is PolarAreaChartDatasetData barChartDatasetData)
3737
barChartDataset.Data?.Add(barChartDatasetData.Data as double?);
3838

39-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
39+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetData", Id, dataLabel, data);
4040

4141
return chartData;
4242
}
@@ -81,7 +81,7 @@ public override async Task<ChartData> AddDataAsync(ChartData chartData, string d
8181
barChartDataset.Data?.Add(barChartDatasetData.Data as double?);
8282
}
8383

84-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (PolarAreaChartDatasetData)x));
84+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDatasetsData", Id, dataLabel, data?.Select(x => (PolarAreaChartDatasetData)x));
8585

8686
return chartData;
8787
}
@@ -100,7 +100,7 @@ public override async Task<ChartData> AddDatasetAsync(ChartData chartData, IChar
100100
if (chartDataset is PolarAreaChartDataset)
101101
{
102102
chartData.Datasets.Add(chartDataset);
103-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.addDataset", Id, (PolarAreaChartDataset)chartDataset);
103+
await SafeInvokeVoidAsync($"{_jsObjectName}.addDataset", Id, (PolarAreaChartDataset)chartDataset);
104104
}
105105

106106
return chartData;
@@ -112,7 +112,7 @@ public override async Task InitializeAsync(ChartData chartData, IChartOptions ch
112112
{
113113
var datasets = chartData.Datasets.OfType<PolarAreaChartDataset>();
114114
var data = new { chartData.Labels, Datasets = datasets };
115-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (PolarAreaChartOptions)chartOptions, plugins);
115+
await SafeInvokeVoidAsync($"{_jsObjectName}.initialize", Id, GetChartType(), data, (PolarAreaChartOptions)chartOptions, plugins);
116116
}
117117
}
118118

@@ -122,7 +122,7 @@ public override async Task UpdateAsync(ChartData chartData, IChartOptions chartO
122122
{
123123
var datasets = chartData.Datasets.OfType<PolarAreaChartDataset>();
124124
var data = new { chartData.Labels, Datasets = datasets };
125-
await JSRuntime.InvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (PolarAreaChartOptions)chartOptions);
125+
await SafeInvokeVoidAsync($"{_jsObjectName}.update", Id, GetChartType(), data, (PolarAreaChartOptions)chartOptions);
126126
}
127127
}
128128

0 commit comments

Comments
 (0)