Blazor server can't find Javasccript file

149 views Asked by At

This is driving me nuts and I'm sure I'm missing something simple because I have zero JS experience. I'm trying to call a js function from the code-behind of a razor page. I keep getting an error it can't find the function.

[2023-11-14T15:49:45.869Z] Error: Microsoft.JSInterop.JSException: Could not find 'saveFile' ('saveFile' was undefined).
findFunction/<@https://localhost:7261/_framework/blazor.server.js:1:497
findFunction@https://localhost:7261/_framework/blazor.server.js:1:465
E@https://localhost:7261/_framework/blazor.server.js:1:2606
beginInvokeJSFromDotNet/s<@https://localhost:7261/_framework/blazor.server.js:1:3494
beginInvokeJSFromDotNet@https://localhost:7261/_framework/blazor.server.js:1:3475
_invokeClientMethod/<@https://localhost:7261/_framework/blazor.server.js:1:72077
_invokeClientMethod@https://localhost:7261/_framework/blazor.server.js:1:72063
_processIncomingData@https://localhost:7261/_framework/blazor.server.js:1:70105
kt/this.connection.onreceive@https://localhost:7261/_framework/blazor.server.js:1:64508
connect/</o.onmessage@https://localhost:7261/_framework/blazor.server.js:1:48842


   at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args)

   at HR_Taxonomy_Change_Management.Pages.Administration.GetSpreadsheet() in C:\Users\v-reedchris\source\repos\HR Taxonomy Change Management\HR Taxonomy Change Management\Pages\Administration.razor.cs:line 169

   at Microsoft.AspNetCore.Components.ComponentBase.CallStateHasChangedOnAsyncCompletion(Task task)

   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState) blazor.server.js:1:116297

I can go into Inspector and it will open the js file in a browser window enter image description here

I added the js file in the _Layout page with the other js file references.

I first put the file in wwwroot/js/saveFile.js, then moved it to the root and no diff. I've tried putting this js file first and putting it last in the loading order in the _Layout page.

I'm starting the download from a button click

private async Task GetSpreadsheet()
{
    IBinaryWorkbookFormatProvider formatProvider = new Telerik.Windows.Documents.Spreadsheet.FormatProviders.OpenXml.Xlsx.XlsxFormatProvider();

    var docService = await AdminDomain.GetReportAsync().ConfigureAwait(false);
    byte[] bytesFromWorkbook = formatProvider.Export(docService);


    //MemoryStream stream = new System.IO.MemoryStream(bytesFromWorkbook);
    //stream.Position = 0;
   // var result = new FileStreamResult(stream, "application/octet-stream");

    await JSRuntime.InvokeAsync<object>("saveFile", "test.xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", bytesFromWorkbook);
    
}

The code is creating a Telerik spreadsheet and sending it into another method that updates the data. Once it comes back it creates a byte[] for the download.

Here is the js function to download a file

function saveFile(file, contentType, content) {
    // Create the URL
    const file = new File([content], filename, { type: contentType });
    const exportUrl = URL.createObjectURL(file);

    // Create the <a> element and click on it
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.href = exportUrl;
    a.download = filename;
    a.target = "_self";
    a.click();

    // We don't need to keep the object URL, let's release the memory
    // On older versions of Safari, it seems you need to comment this line...
    URL.revokeObjectURL(exportUrl);
}
1

There are 1 answers

0
USMC6072 On

After 2 days of banging my head, I found the source. There was an error earlier in the console: Redeclaration of formal parameter file. If you look back at the JS file, there is a parameter named "file" and there is a new File() declaration in the body. I guess JS doesn't like this because as soon as I change the parameter name it was fine.