Blazorise icon indicating copy to clipboard operation
Blazorise copied to clipboard

Markdown Component Javascript Error

Open ninjanerdbgm opened this issue 1 year ago • 1 comments

Describe the bug I have a few Markdown components that are loaded inside of a modal. There is code on a main page to listen for when the modal has been initialized. After it's been initialized, the button to launch the modal becomes available to click.

There is a bug (pictured below) that occurs with the JS Interop that loads the Markdown component and forces a refresh of the page. It seems to occur most often when I navigate away from the page before the modal is ready, but it can occur even after that happens sometimes.

Unfortunately, I cannot share a lot of the source code and had to modify this image a bit to hide some information, but I will share what I can. Picture of the error in the Chrome console: image

To Reproduce Steps to reproduce the behavior:

  1. Create a modal with the following properties:
  • If data is not loaded, do not display any html.
  • If data is loaded, display a Markdown component and bind it to the data.
  • Once the data has loaded, use a notifier service to notify the main page that the modal is ready.
  1. On a main page, include the modal within the HTML and create a button that will launch the modal on click.
  2. Load the main page, but before the modal is ready, navigate away from the main page.
  3. See an error

Expected behavior The page navigates away without error.

Screenshots As I said before, I cannot share a lot of the source, but here is what I can share that's related to the issue:

Here is the top of the Modal file. This prevents any html from displaying if the data has not been loaded yet: image

Here is how the Markdown component is used within the modal: Quick note: The Blazorise.Text component above the Markdown component is used to put an object in the DOM with a specific class based on whether or not there is data in the object tied to the Markdown component. This is then used to style the Markdown component (highlight it if it's empty). Could a future version of the Markdown component include a Class parameter that can be used on the actual textedit part of the Markdown component? If not, this "hack" does the job. image

Here's the OnAfterRenderAsync override in the modal's code-behind that notifies the application when the data for the modal has been loaded. I have a feeling this is partly to blame for the error, but I can't figure out how. image

Here's how the modal is added to the main page: image

Here's the button that launches the modal (when it's ready): image

Modal init in the main page code-behind: image

Modal-ready-setter in the main page code-behind: image

Additional context Let me know if you need more information, but I've shared about as much of the source as I can. Hopefully I've described well-enough how to replicate the issue.

ninjanerdbgm avatar Sep 02 '22 18:09 ninjanerdbgm

I see the very same error message with the RichTextEdit control from time to time (but not investigated any further)

WolfgangKluge avatar Sep 21 '22 22:09 WolfgangKluge

This seems a very similar bug as in #4114.

I've no solution, but an explanation (blazorise tries to call js-functions without waiting for initialization to finish) & a "workaround" (unfortunately only if you compile blazorise on your own).

Since the implementation differs a lot to the richtextedit component, the workaround is a lot different, too.

For the markdown component to work, you have to remove Initialized && from Markdown.razor.cs#L53, move the call base.OnAfterRenderAsync in Markdown.razor.cs#L86 to the end of the function and wait for the completion of the initialization in OnAfterRenderAsync before everywhere if ( !Initialized ) return (like in Markdown.razor.cs#L192 (e.g. with a TaskCompletionSource). That's a kind of a mess (so only to demonstrate the problem).

In addition (to fix another rare error but maybe helps here too), I've changed markdown.js#L54, too. If document.getElementById(elementId) returns null, there will be an javascript error in the aftermath. So I changed that to

let el = document.getElementById(elementId);
if (!el) el = undefined;
const mdeOptions = {
        element: el,

(background: if el === null, then it's considered by easymde as specified while undefined is not. But this prevents only an error. Would be much better to investigate that further to detect the root cause).

Hope that helps to find the bug.

WolfgangKluge avatar Nov 20 '22 18:11 WolfgangKluge