In a .NET MAUI Blazor Hybrid app a razor component renders a link of links such as:
<NavLink href="@($"PharmakaPdfViewer/{row.Id}")" Match="NavLinkMatch.Prefix">...</NavLink>
Here's the code of the PharmakaPdfViewer
component:
@page "/pharmakapdfviewer/{id}"
<h3>PharmakaPdfViewer @Id</h3>
<PdfViewer Class="mb-3" Url="@link" />
@code {
[Parameter]
public string? Id { get; set; }
private string? link = string.Empty;
protected override async Task OnInitializedAsync()
{
var serviceClient = new APIServiceClient();
var dataRow = await serviceClient.GetDataRowAsync(Int32.Parse(Id));
link = dataRow.Link;
await base.OnInitializedAsync();
}
}
PdfViewer
is this Blazor Bootstrap component , which loads the PDF file fetched by the link
URL. The value of the link
property is set in the overridden OnInitializedAsync
, which calls a SOAP web service and gets back the URL of the pdf file corresponding to the provided Id
, for example:
https://localhost:44360/Content/Sample.pdf
The first time, everything works fine and the pdf is shown.
But when I navigate back to the list of links and click another (or the same, for that matter), I always get the following error (in the DevTools Console) and the PdfViewer
remains empty as shown in the screenshot:
Invalid parameter object: need either .data, .range or .url
Error: Invalid parameter object: need either .data, .range or .url
at Module.getDocument (https://0.0.0.0/_content/Blazor.Bootstrap/pdfjs-4.0.379.min.js:21:46398)
at Module.initialize (https://0.0.0.0/_content/Blazor.Bootstrap/blazor.bootstrap.pdf.js:202:11)
at https://0.0.0.0/_framework/blazor.webview.js:1:3050
at new Promise (<anonymous>)
at g.beginInvokeJSFromDotNet (https://0.0.0.0/_framework/blazor.webview.js:1:3007)
at https://0.0.0.0/_framework/blazor.webview.js:1:48020
at EventTarget.<anonymous> (<anonymous>:7:62)
at EmbeddedBrowserWebView.<anonymous> (<anonymous>:1:43835)
at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)
at Microsoft.JSInterop.JSObjectReferenceExtensions.InvokeVoidAsync(IJSObjectReference jsObjectReference, String identifier, Object[] args)
at BlazorBootstrap.PdfViewerJsInterop.InitializeAsync(Object objRef, String elementId, Double scale, Double rotation, String url)
at BlazorBootstrap.PdfViewer.OnAfterRenderAsync(Boolean firstRender)
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
Any idea why this is happening and how can it be fixed?
UPDATE:
I chose the following implementation to force the component to re-render without complaining about string.Empty
or null
:
@if (!string.IsNullOrEmpty(link))
{
<PdfViewer Class="mb-3" Url="@link" />
}
@code {
[Parameter]
public string? Id { get; set; }
private string? link;
protected override async Task OnInitializedAsync()
{
// Set link to null to force removal of the pdf viewer
link = null;
StateHasChanged();
var serviceClient = new APIServiceClient();
var dataRow = await serviceClient.GetDataRowAsync(Int32.Parse(Id));
link = dataRow.Link;
}
}
That seems to do the trick.
Invalid parameter object: need either .data, .range or .url
I can reproduce the error when I set the link
as string.Empty
. And according to the error message, the link
is invalid.
I see you used the async task to get the Url. So you can try to use StateHasChanged();
after you get the Url:
protected override async Task OnInitializedAsync()
{
var serviceClient = new APIServiceClient();
var dataRow = await serviceClient.GetDataRowAsync(Int32.Parse(Id));
link = dataRow.Link;
StateHasChanged();
}