KristofferStrube / Blazor.FileSystemAccess

A Blazor wrapper for the File System Access browser API.
https://kristofferstrube.github.io/Blazor.FileSystemAccess/
MIT License
327 stars 39 forks source link

IndexedDB example not working with new Blazor Web App template #51

Closed mosBrkr closed 3 months ago

mosBrkr commented 3 months ago

Hi there

First of all thanks for the great work!

Actually I try to do something very similar as your 'IndexedDB' example but I'm running into a problem using the latest .NET 8 'Blazor Web App' template.

Steps to reproduce: Create a new 'Blazor Web App' project

Add the following package dependencies:

Configure IndexedDB:

Configure FileSystemAccess:

Replace the whole 'Counter' component by the 'IndexedDB' component (copy/paste from example) and add the necessary usings.

Run and navigate to the 'Counter' page results in the error:

crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not find 'getAttribute' ('getAttribute' was undefined).
      Error: Could not find 'getAttribute' ('getAttribute' was undefined).
          at https://localhost:7041/_framework/blazor.web.js:1:734
          at Array.forEach (<anonymous>)
          at l.findFunction (https://localhost:7041/_framework/blazor.web.js:1:702)
          at b (https://localhost:7041/_framework/blazor.web.js:1:5445)
          at https://localhost:7041/_framework/blazor.web.js:1:3238
          at new Promise (<anonymous>)
          at y.beginInvokeJSFromDotNet (https://localhost:7041/_framework/blazor.web.js:1:3201)
          at Object.ri [as invokeJSJson] (https://localhost:7041/_framework/blazor.web.js:1:165152)
          at https://localhost:7041/_framework/dotnet.runtime.8.0.5.1mqb9hb6bt.js:3:178364
          at Tl (https://localhost:7041/_framework/dotnet.runtime.8.0.5.1mqb9hb6bt.js:3:179198)
Microsoft.JSInterop.JSException: Could not find 'getAttribute' ('getAttribute' was undefined).
Error: Could not find 'getAttribute' ('getAttribute' was undefined).
    at https://localhost:7041/_framework/blazor.web.js:1:734
    at Array.forEach (<anonymous>)
    at l.findFunction (https://localhost:7041/_framework/blazor.web.js:1:702)
    at b (https://localhost:7041/_framework/blazor.web.js:1:5445)
    at https://localhost:7041/_framework/blazor.web.js:1:3238
    at new Promise (<anonymous>)
    at y.beginInvokeJSFromDotNet (https://localhost:7041/_framework/blazor.web.js:1:3201)
    at Object.ri [as invokeJSJson] (https://localhost:7041/_framework/blazor.web.js:1:165152)
    at https://localhost:7041/_framework/dotnet.runtime.8.0.5.1mqb9hb6bt.js:3:178364
    at Tl (https://localhost:7041/_framework/dotnet.runtime.8.0.5.1mqb9hb6bt.js:3:179198)
   at Microsoft.JSInterop.JSRuntime.<InvokeAsync>d__16`1[[System.Int32, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
   at IndexedDbTest.Client.Pages.Counter.OnInitializedAsync() in C:\Users\xxx\source\repos\IndexedDbTest\IndexedDbTest\IndexedDbTest.Client\Pages\Counter.razor:line 43
   at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

As far as I could track it down the JS function 'getAttribute' is not recognized even though the files 'KristofferStrube.Blazor.FileSystemAccess.js', 'KristofferStrube.Blazor.FileSystem.js' and 'KristofferStrube.Blazor.FileAPI.js', are correctly loaded (which all contain a definition for that function).

Do you have an idea why the function isn't recognized?

Edit: Here is a repo containing the mentioned changes: https://github.com/mosBrkr/IndexedDbIssue/

mosBrkr commented 3 months ago

Ok I think I got it resolved! I had to add the following scripts (as also in your example) to my App.razor file:

    <script>
        var path = window.location.pathname.split('/');
        var base = document.getElementsByTagName('base')[0];
        if (window.location.host.includes('localhost')) {
            base.setAttribute('href', '/');
        } else if (path.length > 2) {
            base.setAttribute('href', '/' + path[1] + '/');
        } else if (path[path.length - 1].length != 0) {
            window.location.replace(window.location.origin + window.location.pathname + '/' + window.location.search);
        }
    </script>
    <script>
        function jSReference(element) { return element.valueOf(); }
        function newJSReference() { return {}; }
        function getAttribute(object, attribute) { return object[attribute]; }
        function setAttribute(object, attribute, value) { object[attribute] = value; }
        function toBlob(canvas, blobCallback) {
            var blobWrapper = {};
            canvas.toBlob(
                (blob) => {
                    blobWrapper.blob = blob;
                    blobCallback.objRef.invokeMethodAsync('Callback');
                },
                quality = 1);
            return blobWrapper;
        }
    </script>

Now it works!