How to access instance of JavaScript object in another export function in a blazor class library

  blazor-server-side, c#, ckeditor, javascript

I wrote a small razor class library which implements a custom component for CKEditor 5.

Since the editor is displayed via JavaScript, I need to remove it in the DisposeAsync event from the component.

Here is my interop implementation:

export function setup(id, dotNetReference) {
    var newEditor = null;
        .create(document.querySelector('#ckeditor-' + id), {

            toolbar: {
                items: [
            language: 'de',
            licenseKey: '',

        .then(editor => {
            window.editor = editor;
            editor.model.document.on('change:data', () => {
                let data = editor.getData();

                const el = document.createElement('div');
                el.innerHTML = data;
                if (el.innerText.trim() == '')
                    data = "";

                dotNetReference.invokeMethodAsync('EditorDataChanged', data);
        .catch(error => {
            console.error('Oops, something went wrong!');
            console.error('Please, report the following error on with the build id and the error stack trace:');
            console.warn('Build id: 3qd8y8wn1ree-1342d9v8hd01');


export function destroy() {

    // I need to call editor.destroy(); here

As you can see I have two functions to call: destroy() and setup(id, dotNetReference)

Within the setup method my CKEditor instance becomes created. In the .then closure I have my editor instance which I within my destroy() method. However, even if I set my instance in a variable in the script, I don’t get access to it because the variable does not seem to exists in the destroy() method.

When I put this line inside the destory() method


then it works. However when I have implemented the component two times into a single page then both gets destroyed (which makes sence because both can be identified through the same selector.

This is my CkEditorJsInterop class:

public class CkEditorJsInterop : IAsyncDisposable
        private readonly Lazy<Task<IJSObjectReference>> moduleTask;
        private DotNetObjectReference<InputCkEditor> _reference;

        public CkEditorJsInterop(IJSRuntime jsRuntime)
            moduleTask = new(() => jsRuntime.InvokeAsync<IJSObjectReference>(
               "import", "./_content/CKEditor/ckeditor.js").AsTask());

        public async ValueTask InitAsync(Guid id, DotNetObjectReference<InputCkEditor> reference)
            _reference = reference;
            var module = await moduleTask.Value;
            string newId = id.ToString();
            await module.InvokeVoidAsync("setup", new object[] { newId, reference });

        public async ValueTask DisposeAsync()
            if (moduleTask.IsValueCreated)
                var module = await moduleTask.Value;
                await module.InvokeVoidAsync("destroy");
                await module.DisposeAsync();


Is there any easy way to get this working as expected?

Source: Ask Javascript Questions