serdarciplak / BlazorMonaco

Blazor component for Microsoft's Monaco Editor which powers Visual Studio Code.
https://serdarciplak.github.io/BlazorMonaco/
MIT License
441 stars 99 forks source link

Set Editor Value with data loaded asynchronously #79

Closed msavaria closed 1 year ago

msavaria commented 1 year ago

When my component containing the Monaco editor is loaded, I fetch some data from a database and would like to display it in the editor as an initial value.

However, while the initial value is correctly displayed in the editor, I still the default Blazor error banner with this exception:

Microsoft.JSInterop.JSException: Couldn't find the editor with id: sandalone-editor editors.length: 0 at Microsoft.JSInterop.JSRuntime.InvokeAsync[TValue](Int64 targetInstanceId, String identifier, Object[] args) at Microsoft.JSInterop.JSRuntimeExtensions.InvokeVoidAsync(IJSRuntime jsRuntime, String identifier, Object[] args) at BlazorMonaco.Helpers.JsRuntimeExt.SafeInvokeAsync(IJSRuntime jsRuntime, String identifier, Object[] args) at OnAfterRenderAsync(Boolean firstRender)

image

I am using version 3.0.0 with Blazor Server in Server rendering mode.

Here is my setup:

<StandaloneCodeEditor @ref="Editor" Id="sandalone-editor" ConstructionOptions="EditorConstructionOptions" CssClass="editor" />
@code {
    private string EditorDefaultValue { get; set; }

    private StandaloneEditorConstructionOptions EditorConstructionOptions(StandaloneCodeEditor editor)
    {
        return new StandaloneEditorConstructionOptions
        {
            Language = "csharp",
            GlyphMargin = true,
            Value = "Default Value. Will be replaced by value from database"
        };
    }

    protected override async Task OnInitializedAsync()
    {
        EditorDefaultValue = await MyRepository.GetEditorDefaultValue();
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (Editor != null)
        {
            await Editor.SetValue(EditorDefaultValue);
        }
    }
}
thangavelm commented 1 year ago

Very first time editor take few milliseconds to complete loading. I added a Thread.sleep to overcome this issue.

serdarciplak commented 1 year ago

The StandaloneCodeEditor Blazor component creates the wrapped JS editor instance in its OnAfterRenderAsync method. As the parent component's OnAfterRenderAsync is called before the child component, the JS instance is not yet created at that point. If you set the value any time after the StandaloneCodeEditor's OnAfterRenderAsync method is called, it should work.