Search code examples
c#blazorblazor-webassemblyasp.net-blazor

Blazor How should I get an `IJSObjectReference` when invoking a js function which may return `null`?


For example, I have a module in typescript like:

export function getIndexedDb() : IDBFactory | null
{
    if (window.indexedDB)
        return window.indexedDB;
    else
        return null;
}

Now I want to get an IJSObjectReference of its result, so I have tried this in csharp:

await using var module = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "xxxx.js");
await using var result = await module.InvokeAsync<IJSObjectReference>("getIndexedDb");

It works well when there is a window.indexedDB, but when getIndexedDb() returns null, an error will occur:

Uncaught (in promise) Error: Cannot create a JSObjectReference from the value 'null'.

(And I can't even catch the exception in csharp. The csharp method seems to just stopped here and later codes won't be executed. Is this a bug?)

So what should I do to solve this problem? I don't believe the below one is a good idea:

class Nullable<T>
{
    value: T | null;
    constructor(value: T | null)
    {
        this.value = value;
    }
    getValue() : T | null
    {
        return this.value;
    }
    isNull() : boolean
    {
        return this.value === null;
    }
}

export function getIndexedDb() : Nullable<IDBFactory>
{
    if (window.indexedDB)
        return new Nullable<IDBFactory>(window.indexedDB);
    else
        return new Nullable<IDBFactory>(null);
}

Solution

  • Hardly a solution, but I just worked around this by instead of returning null throwing an exception. This can then be catched on the C# end, and from there return null (or do whatever)

    // JS
    function getXyz() {
      if (xyz)
        return xyz;
      else
        throw 'xyz does not exist';
    }
    
    // C#
    public async ValueTask<IJSObjectReference> GetXyz()
    {
      try
      {
        return await jsRuntime.InvokeAsync<IJSObjectReference>('getXyz');
      }
      catch
      {
        return null;
      }
    }