I was going to use mermaid in Angular by installing the module with npm i -D mermaid
and test with one of the examples of the docs, ok but it does not work. Seems like a frequent problem.
I tried the following code with and without calling the JS API through .
<pre class="mermaid">
graph TD
A[Client] --> B[Load Balancer]
B --> C[Server01]
B --> D[Server02]
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
</pre>
<script type="module">
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: true });
</script>
I tried using this solution but it doesnt work too. (Property 'mermaid' has no initializer and is not definitely assigned in the constructor & Property 'initialize' does not exist on type 'typeof ).
Thanks.
You can import the library and initialize it after Angular has finished rendering the template in the browser. To do so, you can use the afterNextRender
API. Beware that the API is still in developer preview, so it's not stable yet
import { afterNextRender, Component } from "@angular/core";
import mermaid from "mermaid";
@Component({
// ...
})
export class MermaidComponent {
constructor() {
afterNextRender({
read: () => {
void mermaid.init()
}
})
}
}
The
void
beforemermaid.init
can actually be removed. It's just to ignore the linter warning about not waiting for.init
promise
This way Angular will wait until the template is there so Mermaid can be initialized when HTML elements are there.
By using this API, the initialization code only runs on the browser. Which is useful as mermaid
doesn't support server side rendering (yet?)
If you want to use something stable to check if the app is running in a browser or not to perform the initialization, you can also use:
PLATFORM_ID
and isPlatformBrowser
APIs to ensure the init code runs only on the browserAfterViewInit
lifecycle callback to ensure the HTML elements are there when initializingimport { AfterViewInit, Component, Inject, PLATFORM_ID } from "@angular/core";
import { isPlatformBrowser } from "@angular/common";
import mermaid from "mermaid";
@Component({
// ...
})
export class MermaidComponent implements AfterViewInit {
constructor(@Inject(PLATFORM_ID) private _platformId: object) {
}
ngAfterViewInit(): void {
if (isPlatformBrowser(this._platformId)) {
void mermaid.init()
}
}
}
If you're sure you won't ever run your app with server side rendering (SSR) or pre-rendering (SSG) you could actually skip the
if
clause regarding where the code runs on the browser. But just in case it's a good practice to think about it just in case you want to add that later to your project
Created also an example Angular v18 app using mermaid
in case you want to take a look. The important piece is the MermaidComponent
.
The second alternative code is in the classic-way
branch