<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[tnc Blog]]></title><description><![CDATA[Yet another dev blog.]]></description><link>https://nartc.netlify.com</link><generator>GatsbyJS</generator><lastBuildDate>Mon, 04 May 2020 14:50:13 GMT</lastBuildDate><item><title><![CDATA[Using root-provided Injectables in non-DI places]]></title><description><![CDATA[Hi guys, welcome back to my blog 👋. Today, I want to share with you all about a trick that I’ve been using to access
  in places where…]]></description><link>https://nartc.netlify.com/blogs/root-injector/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/root-injector/</guid><pubDate>Sun, 03 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hi guys, welcome back to my blog 👋. Today, I want to share with you all about a trick that I’ve been using to access
&lt;code class=&quot;language-text&quot;&gt;providedIn: &amp;#39;root&amp;#39;&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;Injectables&lt;/code&gt; in places where &lt;strong&gt;Dependency Injection&lt;/strong&gt; (DI) does not make sense in an &lt;strong&gt;Angular&lt;/strong&gt;
application.&lt;/p&gt;
&lt;h3 id=&quot;non-di-places&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#non-di-places&quot; aria-label=&quot;non di places permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Non-DI Places&lt;/h3&gt;
&lt;p&gt;What do I mean by &lt;em&gt;non-DI places&lt;/em&gt;? In an &lt;strong&gt;Angular&lt;/strong&gt; application, there are many different building blocks like: &lt;strong&gt;Component&lt;/strong&gt;,
&lt;strong&gt;Directives&lt;/strong&gt;, &lt;strong&gt;Services&lt;/strong&gt;, and &lt;strong&gt;Modules&lt;/strong&gt; etc. These building blocks are managed by &lt;strong&gt;Angular&lt;/strong&gt; itself and can be accessed by
a built-in &lt;strong&gt;Inversion of Control&lt;/strong&gt; (IoC) container aka &lt;strong&gt;Dependency Injection&lt;/strong&gt;. Beside those, there are different places
that are &lt;strong&gt;not&lt;/strong&gt; managed by &lt;strong&gt;Angular&lt;/strong&gt;’s IoC. Namely, there are &lt;strong&gt;Custom Reactive Form Validators&lt;/strong&gt; and &lt;strong&gt;Custom RxJS Operators&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;and more, but I’ll only touch on validators and operators.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why? &lt;strong&gt;Validators&lt;/strong&gt; and &lt;strong&gt;Operators&lt;/strong&gt; are usually &lt;code class=&quot;language-text&quot;&gt;pure functions&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;static functions&lt;/code&gt; because they will be invoked by &lt;code class=&quot;language-text&quot;&gt;Reactive Form&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;RxJS&lt;/code&gt; respectively.
Because of that, we do not want to write these custom &lt;code class=&quot;language-text&quot;&gt;validators&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;operators&lt;/code&gt; with dependence to an &lt;code class=&quot;language-text&quot;&gt;instance&lt;/code&gt;, aka &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;. However without &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;,
DI becomes tricky because you cannot use the common DI pattern anymore, or &lt;strong&gt;DI via constructor&lt;/strong&gt;.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;84448790445734280000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export class SomeService {
  constructor(private readonly otherService: OtherService) {}

  static someStaticFn() {
    // you can&apos;t access this.otherService in here
  }
}`, `84448790445734280000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; otherService&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OtherService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;someStaticFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// you can&apos;t access this.otherService in here&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;providedin-root&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#providedin-root&quot; aria-label=&quot;providedin root permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;providedIn: ‘root’&lt;/h3&gt;
&lt;p&gt;As some of you might have known, &lt;code class=&quot;language-text&quot;&gt;providedIn: &amp;#39;root&amp;#39;&lt;/code&gt; is an extra option that you can pass in &lt;code class=&quot;language-text&quot;&gt;@Injectable&lt;/code&gt; decorator to let
&lt;strong&gt;Angular&lt;/strong&gt; knows that you want to provide this &lt;code class=&quot;language-text&quot;&gt;Injectable&lt;/code&gt; in the &lt;em&gt;root&lt;/em&gt; &lt;strong&gt;injector&lt;/strong&gt;. Using &lt;code class=&quot;language-text&quot;&gt;providedIn: &amp;#39;root&amp;#39;&lt;/code&gt; will allow you
to have lazy-loaded singleton services.&lt;/p&gt;
&lt;h3 id=&quot;use-case&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#use-case&quot; aria-label=&quot;use case permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Use-case&lt;/h3&gt;
&lt;p&gt;Imagine you have a &lt;code class=&quot;language-text&quot;&gt;LogService&lt;/code&gt; that will handle API errors and log the errors to a 3rd-party logging service, like &lt;strong&gt;ApplicationInsight&lt;/strong&gt;.
Let’s take a look at the following pseudo-code&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;76210262669368430000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`@Injectable({ providedIn: &amp;quot;root&amp;quot; })
export class LogService {
  constructor(private readonly appInsight: ApplicationInsight) {}

  log(error: any) {
    this.appInsight.trackError(error);
  }
}`, `76210262669368430000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; providedIn&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;root&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; appInsight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ApplicationInsight&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;appInsight&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;trackError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To use &lt;code class=&quot;language-text&quot;&gt;LogService&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;58521919334368920000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// somewhere in the codebase
this.httpClient.get(someUrl).pipe(
  catchError((err) =&gt; {
    console.log(err);
    this.logService.log(err);
    return throwError(err);
  })
);`, `58521919334368920000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// somewhere in the codebase&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;httpClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;someUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;catchError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;throwError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above works perfectly fine. But, you do not have ONE API call in the whole application. It is going to get very verbose
to apply that &lt;code class=&quot;language-text&quot;&gt;catchError()&lt;/code&gt; to every single API calls.&lt;/p&gt;
&lt;p&gt;Then you remember you can create &lt;strong&gt;Custom Operator&lt;/strong&gt; to encapsulate reusable logic. You go ahead and start putting together the following operator:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;23065312608207830000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export function logAndRethrowError&lt;TInput = any&gt;(): MonoTypeOperatorFunction&lt;
  TInput
&gt; {
  return catchError((err) =&gt; {
    console.log(err);
    // this.logService.log(err);
    return throwError(err);
  });
}`, `23065312608207830000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; logAndRethrowError&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TInput &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; MonoTypeOperatorFunction&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;
  TInput
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;catchError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// this.logService.log(err);&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;throwError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you realize that you need a &lt;code class=&quot;language-text&quot;&gt;LogService&lt;/code&gt; instance, you start refactoring the &lt;code class=&quot;language-text&quot;&gt;operator&lt;/code&gt; as follow:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;56261598396299470000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`@Injectable({ providedIn: &apos;root&apos; })
export class OperatorUtil {
    constructor(private readonly logService: LogService) {}

    logAndRethrowError&lt;TInput = any&gt;()L MonoTypeOperatorFunction&lt;TInput&gt; {
        return catchError(err =&gt; {
            console.log(err);
            this.logService.log(err);
            return throwError(err);
        });
    }
}`, `56261598396299470000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; providedIn&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;root&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OperatorUtil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; logService&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; LogService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    logAndRethrowError&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TInput &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt; MonoTypeOperatorFunction&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TInput&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;catchError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;logService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;throwError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Everything looks good now and you can start using your custom operator:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;89010817474922180000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`this.httpClient.get(someUrl).pipe(this.operatorUtil.logAndRethrowError());`, `89010817474922180000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;httpClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;someUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;operatorUtil&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;logAndRethrowError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Of course, you would need to inject &lt;code class=&quot;language-text&quot;&gt;OperatorUtil&lt;/code&gt; in wherever you’re calling &lt;code class=&quot;language-text&quot;&gt;this.httpClient.get(...)&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The above approach works fine but there are a couple of things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You would not want every new custom operators now need to be in &lt;code class=&quot;language-text&quot;&gt;OperatorUtil&lt;/code&gt; as instance methods&lt;/li&gt;
&lt;li&gt;You would not like that You need to start injecting &lt;code class=&quot;language-text&quot;&gt;OperatorUtil&lt;/code&gt; everywhere you want to use those custom operators&lt;/li&gt;
&lt;li&gt;You would want to stick with Pure Functions for custom operators.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;solution&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#solution&quot; aria-label=&quot;solution permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Solution&lt;/h3&gt;
&lt;p&gt;As you can see, without custom operators being instance methods, there is no way you can access the &lt;code class=&quot;language-text&quot;&gt;this.logService&lt;/code&gt; inside
of your custom operators. Is there a solution? Yes, there is.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This solution applies to &lt;strong&gt;Custom Validators&lt;/strong&gt; as &lt;strong&gt;Custom Operators&lt;/strong&gt;. And this solution only works with &lt;code class=&quot;language-text&quot;&gt;providedIn: &amp;#39;root&amp;#39;&lt;/code&gt; injectables.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The solution is to create a class called &lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; (in fact, you can call it whatever you want) with some static properties and methods to
keep track of the root &lt;strong&gt;Injector&lt;/strong&gt; that gets all the &lt;code class=&quot;language-text&quot;&gt;providedIn: &amp;#39;root&amp;#39;&lt;/code&gt; providers.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;94811232371416920000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export class RootInjector {
  private static rootInjector: Injector;
  private static readonly \$injectorReady = new BehaviorSubject(false);
  readonly injectorReady\$ = this.\$injectorReady.asObservable();

  static setInjector(injector: Injector) {
    if (this.rootInjector) {
      return;
    }

    this.rootInjector = injector;
    this.\$injectorReady.next(true);
  }

  static get&lt;T&gt;(
    token: Type&lt;T&gt; | InjectionToken&lt;T&gt;,
    notFoundValue?: T,
    flags?: InjectFlags
  ): T {
    try {
      return this.rootInjector.get(token, notFoundValue, flags);
    } catch (e) {
      console.error(
        \`Error getting \${token} from RootInjector. This is likely due to RootInjector is undefined. Please check RootInjector.rootInjector value.\`
      );
      return null;
    }
  }
}`, `94811232371416920000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RootInjector&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; rootInjector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; $injectorReady &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BehaviorSubject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injectorReady$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$injectorReady&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;asObservable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rootInjector&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rootInjector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; injector&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$injectorReady&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    token&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; InjectionToken&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    notFoundValue&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    flags&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; InjectFlags
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rootInjector&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; notFoundValue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; flags&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Error getting &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;token&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; from RootInjector. This is likely due to RootInjector is undefined. Please check RootInjector.rootInjector value.&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above is &lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; implementation. Now the question is “where to use it?” The answer is “main.ts”. In &lt;code class=&quot;language-text&quot;&gt;main.ts&lt;/code&gt; (or your entry file), you’ll always
call &lt;code class=&quot;language-text&quot;&gt;bootstrapModule()&lt;/code&gt; to start bootstraping your &lt;strong&gt;Angular&lt;/strong&gt; application. &lt;code class=&quot;language-text&quot;&gt;bootstrapModule()&lt;/code&gt; returns a &lt;code class=&quot;language-text&quot;&gt;Promise&lt;/code&gt; with the &lt;code class=&quot;language-text&quot;&gt;ModuleRef&lt;/code&gt; as the resolved value.
And there is a property called &lt;code class=&quot;language-text&quot;&gt;injector&lt;/code&gt; on the &lt;code class=&quot;language-text&quot;&gt;ModuleRef&lt;/code&gt; that is exactly the root &lt;strong&gt;injector&lt;/strong&gt; that we’re interested in. To be more accurate, the &lt;code class=&quot;language-text&quot;&gt;injector&lt;/code&gt;
on &lt;code class=&quot;language-text&quot;&gt;ModuleRef&lt;/code&gt; is whatever module’s injector we use to bootstrap. In most cases, it is &lt;code class=&quot;language-text&quot;&gt;AppModule&lt;/code&gt;. So you can guarantee that the Injectables which are provided in
this &lt;code class=&quot;language-text&quot;&gt;injector&lt;/code&gt; will be singletons throughout your application.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;49345702715640450000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`platformBrowserDynamic.bootstrapModule(AppModule).then((ngModuleRef) =&gt; {
  RootInjector.setInjector(ngModuleRef.injector);
});`, `49345702715640450000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;platformBrowserDynamic&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bootstrapModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;AppModule&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ngModuleRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  RootInjector&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ngModuleRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;injector&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now back to our &lt;code class=&quot;language-text&quot;&gt;logAndRethrowError()&lt;/code&gt; operator, we can leverage &lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; to get the &lt;code class=&quot;language-text&quot;&gt;LogService&lt;/code&gt; singleton (since &lt;code class=&quot;language-text&quot;&gt;LogService&lt;/code&gt; is &lt;code class=&quot;language-text&quot;&gt;providedIn: &amp;#39;root&amp;#39;&lt;/code&gt;)&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;40080453500705325000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export function logAndRethrowError&lt;TInput = any&gt;(
  beforeRethrow?: (err?: any) =&gt; void
): MonoTypeOperatorFunction&lt;TInput&gt; {
  const logService = RootInjector.get(LogService);
  return catchError((err) =&gt; {
    console.log(err);
    logService.log(err);
    beforeRethrow?.(err);
    return throwError(err);
  });
}`, `40080453500705325000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; logAndRethrowError&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TInput &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  beforeRethrow&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; MonoTypeOperatorFunction&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TInput&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; logService &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; RootInjector&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LogService&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;catchError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    logService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    beforeRethrow&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;throwError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;I added a &lt;code class=&quot;language-text&quot;&gt;beforeRethrow&lt;/code&gt; callback in case you want to execute additional logic before rethrow happens.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then, we can change our &lt;code class=&quot;language-text&quot;&gt;httpClient.get()&lt;/code&gt; implementation a little bit to use &lt;code class=&quot;language-text&quot;&gt;logAndRethrowError()&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;19186853657425162000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`this.httpClient.get(someUrl).pipe(logAndRethrowError());`, `19186853657425162000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;httpClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;someUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;logAndRethrowError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;635832071437536500&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// with callback
this.httpClient.get(someUrl).pipe(
  logAndRethrowError((err) =&gt; {
    this.toastService.error(err);
  })
);`, `635832071437536500`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// with callback&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;httpClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;someUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;logAndRethrowError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;toastService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;summary&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#summary&quot; aria-label=&quot;summary permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Summary&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; is a nice and elegant way of keeping track of the root &lt;strong&gt;injector&lt;/strong&gt; so that you can access the Injectables
anywhere throughout your application. Although, there are &lt;em&gt;gotchas&lt;/em&gt;. &lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; depends on the actual bootstrap process
of &lt;code class=&quot;language-text&quot;&gt;AppModule&lt;/code&gt; and if you try to access &lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; before &lt;code class=&quot;language-text&quot;&gt;AppModule&lt;/code&gt; has been bootstrapped, exceptions will be thrown.
What are such occasions? &lt;code class=&quot;language-text&quot;&gt;APP_INITIALIZER&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Guards&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;Resolvers&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;ErrorHandler&lt;/code&gt; that might halt the bootstrap process.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;RootInjector.injectorReady$&lt;/code&gt; is a workaround for some cases where you want to use &lt;code class=&quot;language-text&quot;&gt;RootInjector&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;AppComponent&lt;/code&gt; to initialize
some data.&lt;/p&gt;
&lt;p&gt;Hopefully, you learn something new today. Thanks for reading and I’ll see you soon 🤞&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What's new in AutoMapper v6?]]></title><description><![CDATA[Hi everyone, long time no see 👋. Today, I am very excited to talk to you guys about AutoMapper () version 6.
This is a release with an…]]></description><link>https://nartc.netlify.com/blogs/automapper-v6/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/automapper-v6/</guid><pubDate>Fri, 20 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hi everyone, long time no see 👋. Today, I am very excited to talk to you guys about &lt;strong&gt;AutoMapper&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt;) version 6.
This is a release with an &lt;em&gt;almost complete&lt;/em&gt; rewritten core and some small changes to the public API, for the better.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you do not know about &lt;strong&gt;AutoMapper&lt;/strong&gt;, you can find out more about it via this blog post &lt;a href=&quot;/blogs/introduction-to-automapper-typescript&quot;&gt;Introduction to AutoMapper TypeScript&lt;/a&gt; or &lt;a href=&quot;https://github.com/nartc/mapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;update-03242020&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#update-03242020&quot; aria-label=&quot;update 03242020 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Update 03/24/2020&lt;/h2&gt;
&lt;p&gt;I have updated the benchmark code and have ran all benchmarks 100 times instead of 10 times. You can check out the benchmark repo &lt;a href=&quot;https://github.com/nartc/ng-automapper-bench&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;whats-new&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#whats-new&quot; aria-label=&quot;whats new permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;What’s new?&lt;/h2&gt;
&lt;p&gt;This v6 release does not contain many changes regarding the public API but performance, bundle-size, critical bug fixes, and a stab at &lt;strong&gt;JavaScript&lt;/strong&gt; support were the main targets of this release. Let’s explore
💪&lt;/p&gt;
&lt;h2 id=&quot;performance&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#performance&quot; aria-label=&quot;performance permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Performance&lt;/h2&gt;
&lt;p&gt;For libraries that deal with transforming data like &lt;strong&gt;AutoMapper&lt;/strong&gt;, performance is not to take lightly. However before we dive into the performance of &lt;strong&gt;AutoMapper&lt;/strong&gt;, I want to
emphasize the initial purpose of me creating this library which is to transform &lt;strong&gt;Domain Model (database)&lt;/strong&gt; to &lt;strong&gt;View Model (client/frontend)&lt;/strong&gt; via API calls. This is to point out that
the number of items going back and forth Network Calls should not be too many like hundreds of thousands or millions of objects going through a single network call. With that in mind,
&lt;strong&gt;mapping&lt;/strong&gt; such big amount of objects at once is not realistic in my opinion. Although, I would love for &lt;strong&gt;AutoMapper&lt;/strong&gt; to have better performance than not. Let’s take a look at some simple statistics, shall we?&lt;/p&gt;
&lt;p&gt;First, let’s look at the models I am going to use for this benchmark:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;54138227621060800000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class Bio {
  job: string;
  age: number;
  birthday: Date;
}

class User {
  firstName: string;
  lastName: string;
  bio: Bio;
}`, `54138227621060800000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bio&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  age&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Bio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and the correspond view models &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;3615649315835645000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class BioVm {
  job: string;
  isAdult: boolean;
  birthday: string;
}

class UserVm {
  first: string;
  last: string;
  full: string;
  bio: BioVm;
}`, `3615649315835645000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BioVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  isAdult&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  first&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  last&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  full&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;along with the following configuration:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;80121318045349920000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`Mapper.createMap(User, UserVm)
  .forMember(
    (d) =&gt; d.first,
    mapFrom((s) =&gt; s.firstName)
  )
  .forMember(
    (d) =&gt; d.last,
    mapFrom((s) =&gt; s.lastName)
  )
  .forMember(
    (d) =&gt; d.full,
    mapFrom((s) =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
  );
Mapper.createMap(Bio, BioVm)
  .forMember(
    (d) =&gt; d.isAdult,
    mapFrom((s) =&gt; s.age &gt; 18)
  )
  .forMember(
    (d) =&gt; d.birthday,
    mapFrom((s) =&gt; s.birthday.toDateString())
  );`, `80121318045349920000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isAdult&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;birthday&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;birthday&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Executing &lt;strong&gt;map&lt;/strong&gt; from &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt; with the above configuration for 1K, 10K, and 100K items yields the following result:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;1K items&lt;/th&gt;
&lt;th&gt;10K items&lt;/th&gt;
&lt;th&gt;100K items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; v5&lt;/td&gt;
&lt;td&gt;~9ms&lt;/td&gt;
&lt;td&gt;~88ms&lt;/td&gt;
&lt;td&gt;~959ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; v6&lt;/td&gt;
&lt;td&gt;~8ms&lt;/td&gt;
&lt;td&gt;~81ms&lt;/td&gt;
&lt;td&gt;~785ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Each benchmark was ran ~10~ 100 times for each category 1K, 10K, and 100K then the average was taken&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As you can see, &lt;strong&gt;AutoMapper&lt;/strong&gt; v6 is slightly faster than v5, about 10-25% faster. And what really changed in v6? &lt;strong&gt;AutoMapper&lt;/strong&gt; v6 does have some optimizations applied to it, as follow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Loops Optimization: v6 uses &lt;code class=&quot;language-text&quot;&gt;while&lt;/code&gt; loops that &lt;code class=&quot;language-text&quot;&gt;for let&lt;/code&gt; (the original &lt;code class=&quot;language-text&quot;&gt;for&lt;/code&gt; loop with index variable) was used in important places like: &lt;strong&gt;map&lt;/strong&gt; and &lt;strong&gt;initializing mapping properties&lt;/strong&gt;.
In areas where &lt;code class=&quot;language-text&quot;&gt;for let&lt;/code&gt; is still used, v6 has the property &lt;code class=&quot;language-text&quot;&gt;length&lt;/code&gt; cached to avoid additional &lt;code class=&quot;language-text&quot;&gt;property lookup&lt;/code&gt; for every iterations.&lt;/li&gt;
&lt;li&gt;Accessing Array Index: v6 moves a large part of the core’s data structures from &lt;code class=&quot;language-text&quot;&gt;Object&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; to also avoid &lt;code class=&quot;language-text&quot;&gt;property lookup&lt;/code&gt;. About this technique, there are still areas in the code base where this can be applied further.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;You can learn more about &lt;strong&gt;Accessing Array Index&lt;/strong&gt; from the talk &lt;a href=&quot;https://www.youtube.com/watch?v=EqSRpkMRyY4&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;How we make Angular fast&lt;/a&gt; by Misko Hevery&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With the permission from &lt;a href=&quot;https://twitter.com/YannRenaudin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Yann Renaudin&lt;/a&gt;, &lt;a href=&quot;https://github.com/nobrainr/morphism&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;morphism&lt;/a&gt; author, I would like to share &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; benchmark with the same mapping configuration as above:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;7818797967584024000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const morphismSchema = {
  first: &amp;quot;firstName&amp;quot;,
  last: &amp;quot;lastName&amp;quot;,
  full: ({ firstName, lastName }) =&gt; firstName + &amp;quot; &amp;quot; + lastName,
  bio: {
    job: &amp;quot;bio.job&amp;quot;,
    isAdult: ({ bio }) =&gt; bio.age &gt; 18,
    birthday: ({ bio }) =&gt; bio.birthday.toDateString(),
  },
};`, `7818797967584024000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; morphismSchema &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  first&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;firstName&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  last&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lastName&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;full&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; lastName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bio.job&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;isAdult&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; bio &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; bio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; bio &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; bio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;birthday&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Each benchmark was ran ~10~ 100 times for each category 1K, 10K, and 100K then the average was taken&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;1K items&lt;/th&gt;
&lt;th&gt;10K items&lt;/th&gt;
&lt;th&gt;100K items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~15ms&lt;/td&gt;
&lt;td&gt;~144ms&lt;/td&gt;
&lt;td&gt;~1436ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;create-mapper&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~15ms&lt;/td&gt;
&lt;td&gt;~145ms&lt;/td&gt;
&lt;td&gt;~1464ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; v6&lt;/td&gt;
&lt;td&gt;~8ms&lt;/td&gt;
&lt;td&gt;~81ms&lt;/td&gt;
&lt;td&gt;~785ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This is just a simple comparison solely on the &lt;strong&gt;mapping&lt;/strong&gt; part of the two libraries. Utility wise, &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; is a fantastic library that supports mapping with &lt;strong&gt;schema configuration&lt;/strong&gt; and this suits
perfectly with &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt; projects, which do not have &lt;code class=&quot;language-text&quot;&gt;classes&lt;/code&gt; to model the data in the projects. You can also store the &lt;strong&gt;schema configuration&lt;/strong&gt; elsewhere (database, CDN) and reuse the &lt;strong&gt;schema configuration&lt;/strong&gt; without having the schema inside of your source code.
If you find &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; interesting, please check it out at &lt;a href=&quot;https://github.com/nobrainr/morphism&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;. Thank you &lt;a href=&quot;https://twitter.com/YannRenaudin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Yann&lt;/a&gt; for allowing me to take &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; to do a simple
benchmark for &lt;strong&gt;AutoMapper&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;small-bundle&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#small-bundle&quot; aria-label=&quot;small bundle permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Small Bundle&lt;/h2&gt;
&lt;p&gt;Overall, the bundle-size of v6 is sightly smaller than v5. All of the utility functions and some of the core parts were cleaned up pretty heavily.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 431px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0954430092f37881645b1e54b07aecfc/369db/master.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABP0lEQVQoz61STU+DQBDl39cm/AoTYj20iQeNHjTBG7fyC5pILRTYLbVQvnnujEK3sUYOTvIyZHg7++bNGrgQXdfhr/iNY/Q/KPegqKqakRcF56ZpUFYViqLkb/3MxYZt2w6gCCPBeFtvOO+SPbZhjPUmwCHNqN0PEZSNsSOOtWBQuFwuYds2XNflEbdhhLquB/UUQRDAcRz4vq/4Lmo1ehjFyoL2pLAnW5aF6XQK0zRx//SC65s5k/WGq9UKi8UCt7MZJpMrPD6/Yn73ACF3p4a9Qs/zIKWEFAL7jwOiWLBSfZyyLJFlmULK3ET5KnfJuYe6f/42RCwkZ9qm3ixQNT8IeUFCJqiUHcSlRb2rRaW8KM1D8iM7HvmZUKYnojcsVD3Pe+TK3y8+XUy16ttvA/8cBinKz27XUGjIR0DxPgF/tVKuDdcLPAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;master&quot;
        title=&quot;master&quot;
        src=&quot;/static/0954430092f37881645b1e54b07aecfc/369db/master.png&quot;
        srcset=&quot;/static/0954430092f37881645b1e54b07aecfc/7b64c/master.png 160w,
/static/0954430092f37881645b1e54b07aecfc/4e610/master.png 320w,
/static/0954430092f37881645b1e54b07aecfc/369db/master.png 431w&quot;
        sizes=&quot;(max-width: 431px) 100vw, 431px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;AutoMapper v5 bundle-size&lt;/em&gt;
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 433px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b479a1493e757b87949f625d23c11a31/293b3/next.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 53.125%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABXklEQVQoz41SS0/CQBDmRxM8ceOXcIaLHGyqWIOahmhKJRAPxBgjfdDS8ixtabefu4sL2NLESSY7O/vNt/Oq4IJkWXY8hV2GyUvlv0BBnv8kj+eEhBCuJ3AGf7GEO/fxbViwHRer9Yb7LNvhp4g7r+ZihkLiOEYYRQcNI8T7PdcoigvYc+IKM2zbhuM48DwPSZLAMIyyf2gggWmanICdaZr+KZ9n2Gq10Gg00Gw2Icsy6vU6+q8D3Nwq+Pj84mAROB6PUa1WMZlMcFWrQZLvcN9T0XvunzKUJAndbheKokDTNH4fvI3w8KhialrHspiwKjqda+i6jna7jYE+xJP6guHo/UQoJKT94b2K9xcnyfq5DXa0LSm3xRvD78IQm21wIBTOKZ2oO/d4VqvVurCLS+ozrRnsmUOnPaPkATx/Qe8uLOpjsaVTzu9Y2X4WFltkQJj+7mN+L4+Y3DshRd8PnwdMZHbMDMsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;next&quot;
        title=&quot;next&quot;
        src=&quot;/static/b479a1493e757b87949f625d23c11a31/293b3/next.png&quot;
        srcset=&quot;/static/b479a1493e757b87949f625d23c11a31/7b64c/next.png 160w,
/static/b479a1493e757b87949f625d23c11a31/4e610/next.png 320w,
/static/b479a1493e757b87949f625d23c11a31/293b3/next.png 433w&quot;
        sizes=&quot;(max-width: 433px) 100vw, 433px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;AutoMapper v6 bundle-size&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Bundle-size is provided by &lt;a href=&quot;https://bundlephobia.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Bundlephobia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;On other note, let’s take another look at the above &lt;strong&gt;mapping configuration&lt;/strong&gt; with the difference between v5 and v6:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;40288759992084324000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// v5
Mapper.createMap(User, UserVm)
  .forMember(
    (d) =&gt; d.first,
    (opts) =&gt; opts.mapFrom((s) =&gt; s.firstName)
  )
  .forMember(
    (d) =&gt; d.last,
    (opts) =&gt; opts.mapFrom((s) =&gt; s.lastName)
  )
  .forMember(
    (d) =&gt; d.full,
    (opts) =&gt; opts.mapFrom((s) =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
  );

// v6
Mapper.createMap(User, UserVm)
  .forMember(
    (d) =&gt; d.first,
    mapFrom((s) =&gt; s.firstName)
  )
  .forMember(
    (d) =&gt; d.last,
    mapFrom((s) =&gt; s.lastName)
  )
  .forMember(
    (d) =&gt; d.full,
    mapFrom((s) =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
  );`, `40288759992084324000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// v5&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// v6&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Did you spot the difference? In v6, the second parameter of &lt;code class=&quot;language-text&quot;&gt;forMember()&lt;/code&gt; is &lt;strong&gt;no longer&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;ForMemberOptions&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;ForMemberOptions&lt;/code&gt; is an interface that contains all &lt;strong&gt;mapping operations&lt;/strong&gt; like:
&lt;code class=&quot;language-text&quot;&gt;mapFrom()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;mapWith()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;ignore()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;condition()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;fromValue()&lt;/code&gt;, and some others. In v6, these &lt;strong&gt;mapping operations&lt;/strong&gt; are separated into their own &lt;code class=&quot;language-text&quot;&gt;Pure Functions&lt;/code&gt;. This allows for &lt;code class=&quot;language-text&quot;&gt;tree-shaking&lt;/code&gt; tools to do their job.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;tree-shaking&lt;/code&gt; is a step during Build/Bundle. It means to eliminating dead-code (unused code). Dead code, like &lt;code class=&quot;language-text&quot;&gt;Functions&lt;/code&gt; that are declared but are not used, will be removed from the final bundle which results in a much smaller bundle-size. Only pay for what you use kind of thing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;critical-bug&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#critical-bug&quot; aria-label=&quot;critical bug permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Critical Bug&lt;/h2&gt;
&lt;p&gt;In the previous versions of &lt;strong&gt;AutoMapper&lt;/strong&gt;, all of the &lt;strong&gt;Mappings&lt;/strong&gt; and &lt;strong&gt;Profiles&lt;/strong&gt; were stored in a form of &lt;code class=&quot;language-text&quot;&gt;Object&lt;/code&gt; (or &lt;code class=&quot;language-text&quot;&gt;Dictionary&lt;/code&gt;) with their &lt;code class=&quot;language-text&quot;&gt;prototype.name&lt;/code&gt; as &lt;code class=&quot;language-text&quot;&gt;key&lt;/code&gt;. And whatever comes will come, these
&lt;code class=&quot;language-text&quot;&gt;Object&lt;/code&gt; uses &lt;code class=&quot;language-text&quot;&gt;prototype.name&lt;/code&gt; as their &lt;code class=&quot;language-text&quot;&gt;keys&lt;/code&gt; so when a consumer uses the library in Production environment, plugins like &lt;code class=&quot;language-text&quot;&gt;Uglify&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;Terser&lt;/code&gt; will minify the source code, resulting in these &lt;strong&gt;Mapping&lt;/strong&gt; and &lt;strong&gt;Profile&lt;/strong&gt;
class name are also “uglified” which ultimately leads to duplicate &lt;code class=&quot;language-text&quot;&gt;keys&lt;/code&gt; forcing &lt;strong&gt;AutoMapper&lt;/strong&gt; to throw exceptions left and right.&lt;/p&gt;
&lt;p&gt;v6 changes how it stores these classes with the use of some Singleton &lt;strong&gt;Storages&lt;/strong&gt;. These singletons use &lt;code class=&quot;language-text&quot;&gt;WeakMap&lt;/code&gt; to store the classes themselves as &lt;code class=&quot;language-text&quot;&gt;key&lt;/code&gt; instead of using &lt;code class=&quot;language-text&quot;&gt;prototype.name&lt;/code&gt;. This guarantees the uniqueness
of the &lt;code class=&quot;language-text&quot;&gt;keys&lt;/code&gt; even after the minification process.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;55133853605173330000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// To demonstrate my point about prototype.name
class Foo {}

console.log(Foo.name); // logs Foo
console.log(Foo.prototype.constructor.name); // logs Foo`, `55133853605173330000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// To demonstrate my point about prototype.name&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Foo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// logs Foo&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// logs Foo&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;javascript-support&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#javascript-support&quot; aria-label=&quot;javascript support permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;JavaScript Support&lt;/h2&gt;
&lt;p&gt;Before v6, support for &lt;strong&gt;JavaScript&lt;/strong&gt; is essentially non-existent. &lt;strong&gt;AutoMapper&lt;/strong&gt; has been working only with &lt;strong&gt;TypeScript&lt;/strong&gt; projects. From v6, this will change as &lt;strong&gt;AutoMapper&lt;/strong&gt; will provide a new API
to work with &lt;strong&gt;JavaScript&lt;/strong&gt;. Before introducing this API, I would like to skim through how &lt;strong&gt;AutoMapper&lt;/strong&gt; works so you guys can understand how it has only been supporting &lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AutoMapper&lt;/strong&gt; works on the concept of &lt;strong&gt;Metadata&lt;/strong&gt; (data about data) of the Models. For example, the above &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; model has the following information: &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt; is a string, and &lt;code class=&quot;language-text&quot;&gt;bio&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;Bio&lt;/code&gt;.
These are so-called &lt;strong&gt;Metadata&lt;/strong&gt;. To get a hold of these information at runtime, &lt;strong&gt;AutoMapper&lt;/strong&gt; uses a decorator &lt;code class=&quot;language-text&quot;&gt;@AutoMap()&lt;/code&gt;. Afterwards, &lt;code class=&quot;language-text&quot;&gt;MetadataStorage&lt;/code&gt; will step in and store these metadata, that &lt;code class=&quot;language-text&quot;&gt;@AutoMap()&lt;/code&gt; provides, for each unique Model.
In &lt;strong&gt;Vanilla JavaScript&lt;/strong&gt; projects, it is quite complicated to setup your project to use &lt;code class=&quot;language-text&quot;&gt;decorators&lt;/code&gt;, and &lt;strong&gt;AutoMapper&lt;/strong&gt; itself did not have any API to support &lt;strong&gt;JavaScript&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The API that v6 will provide is: &lt;code class=&quot;language-text&quot;&gt;createMapMetadata()&lt;/code&gt;. This API will simulate how &lt;code class=&quot;language-text&quot;&gt;@AutoMap()&lt;/code&gt; works so metadata can be stored. However, this early-versioned API will still require the consumers to provide some amount of boiler-plate code&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;52497728617914480000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class User {}
class UserVm {}

class Bio {}
class BioVm {}`, `52497728617914480000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bio&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BioVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt; does not have Type Declaration so &lt;code class=&quot;language-text&quot;&gt;fields&lt;/code&gt; do not have to be declared. But these empty classes are required to ensure the uniqueness of the Models.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;94321621809761830000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`createMapMetadata(Bio, {
  job: String,
  age: Number,
  birthday: Date,
});
createMapMetadata(User, {
  firstName: String,
  lastName: String,
  bio: Bio,
});
createMapMetadata(BioVm, {
  job: String,
  isAdult: Boolean,
  birthday: String,
});
createMapMetadata(UserVm, {
  first: String,
  last: String,
  full: String,
  bio: BioVm,
});`, `94321621809761830000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  age&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Number&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  isAdult&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Boolean&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  first&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  last&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  full&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Too boiler-platey right? Well, consumers do not have to provide information for each and every fields like above. Only fields that &lt;strong&gt;ARE NOT&lt;/strong&gt; configured manually by &lt;code class=&quot;language-text&quot;&gt;.forMember()&lt;/code&gt; are required to be provided.
So with the configuration in the beginning of the blog, &lt;code class=&quot;language-text&quot;&gt;isAdult&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;birthday&lt;/code&gt; from &lt;code class=&quot;language-text&quot;&gt;BioVm&lt;/code&gt; do not have to be provided in &lt;code class=&quot;language-text&quot;&gt;createMapMetadata&lt;/code&gt;. Likewise, &lt;code class=&quot;language-text&quot;&gt;first&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;last&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;full&lt;/code&gt; do not have to be provided for &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt;.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;28871230866171650000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`createMapMetadata(Bio, {
  job: String,
  age: Number,
  birthday: Date,
});
createMapMetadata(User, {
  firstName: String,
  lastName: String,
  bio: Bio,
});

createMapMetadata(BioVm, {
  job: String,
});
createMapMetadata(UserVm, {
  bio: BioVm,
});`, `28871230866171650000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  age&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Number&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The similar is applied for when consumers configure reverse mapping for &lt;code class=&quot;language-text&quot;&gt;UserVm -&amp;gt; User&lt;/code&gt; (or &lt;code class=&quot;language-text&quot;&gt;BioVm -&amp;gt; Bio&lt;/code&gt;). Fields that &lt;strong&gt;ARE&lt;/strong&gt; configured manually by &lt;code class=&quot;language-text&quot;&gt;.forPath()&lt;/code&gt; (if &lt;code class=&quot;language-text&quot;&gt;reverseMap()&lt;/code&gt; is used) and/or &lt;code class=&quot;language-text&quot;&gt;.forMember()&lt;/code&gt;
are not required to be provided in &lt;code class=&quot;language-text&quot;&gt;createMapMetadata&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;can-i-try&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#can-i-try&quot; aria-label=&quot;can i try permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Can I try?&lt;/h2&gt;
&lt;p&gt;You can try out &lt;strong&gt;AutoMapper&lt;/strong&gt; v6 by installing the next version of the library&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm i @nartc/automapper@next&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;migrate-from-v5&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#migrate-from-v5&quot; aria-label=&quot;migrate from v5 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Migrate from v5&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Like mentioned above, the &lt;strong&gt;mapping operations&lt;/strong&gt; are separate functions in v6. So you configuration needs to be changed:&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;84330171426046690000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// before
Mapper.createMap(User, UserVm)
    .forMember(d =&gt; d.full, opts =&gt; opts.mapFrom(s =&gt; s.first + &apos; &apos; + s.last)
    .forMember(d =&gt; d.foo, opts =&gt; opts.ignore());

// after
Mapper.createMap(User, UserVm)
    .forMember(d =&gt; d.full, mapFrom(s =&gt; s.first + &apos; &apos; + s.last)
    .forMember(d =&gt; d.foo, ignore())`, `84330171426046690000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// before&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// after&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Mapper.initialize()&lt;/code&gt; has been deprecated. Please use &lt;code class=&quot;language-text&quot;&gt;Mapper.createMap()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Mapper.addProfile()&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;Mapper.withGlobalSettings()&lt;/code&gt; directly.&lt;/li&gt;
&lt;li&gt;All functions that receive &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;NamingConvention&lt;/code&gt; as arguments are now expecting the &lt;code class=&quot;language-text&quot;&gt;Class&lt;/code&gt; instead of the instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;40827153674660920000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// before
Mapper.createMap(User, UserVm, {
  sourceMemberNamingConvention: new PascalCaseNamingConvention(),
});

// after
Mapper.createMap(User, UserVm, {
  sourceMemberNamingConvention: PascalCaseNamingConvention,
});`, `40827153674660920000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// before&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sourceMemberNamingConvention&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PascalCaseNamingConvention&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// after&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sourceMemberNamingConvention&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PascalCaseNamingConvention&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can learn more from the &lt;a href=&quot;https://automapper.netlify.com/docs/next/introduction/why&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;documentation&lt;/a&gt; for the next version.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Again, I am very excited to share these changes with you in &lt;strong&gt;AutoMapper&lt;/strong&gt; v6. Same as my previous blog posts about &lt;strong&gt;AutoMapper&lt;/strong&gt;, I hope people will give &lt;strong&gt;AutoMapper&lt;/strong&gt; a try should the library fits their use-cases.
Thank you for reading and I will see you in the next one. 👋&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Có gì mới với AutoMapper v6?]]></title><description><![CDATA[Xin chào mọi người, đã lâu không gặp 👋. Hôm nay, mình rất phấn khởi khi được giới thiệu về AutoMapper () v6 đến với mọi người.
Đây là bản…]]></description><link>https://nartc.netlify.com/blogs/automapper-v6/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/automapper-v6/</guid><pubDate>Fri, 20 Mar 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Xin chào mọi người, đã lâu không gặp 👋. Hôm nay, mình rất phấn khởi khi được giới thiệu về &lt;strong&gt;AutoMapper&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt;) v6 đến với mọi người.
Đây là bản release với phần core gần như được &lt;em&gt;rewrite&lt;/em&gt; lại toàn bộ và public API có phần thay đổi chút ít, theo chiều hướng tích cực hơn.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nếu như các bạn chưa biết về &lt;strong&gt;AutoMapper&lt;/strong&gt; thì có thể tìm hiểu bài blog này của mình &lt;a href=&quot;/blogs/introduction-to-automapper-typescript&quot;&gt;Introduction to AutoMapper TypeScript&lt;/a&gt; hoặc &lt;a href=&quot;https://github.com/nartc/mapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;cập-nhật-ngày-24-03-2020&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#c%E1%BA%ADp-nh%E1%BA%ADt-ng%C3%A0y-24-03-2020&quot; aria-label=&quot;cập nhật ngày 24 03 2020 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cập nhật ngày 24-03-2020&lt;/h2&gt;
&lt;p&gt;Mình cập nhật lại benchmark và chạy lại tất cả benchmark 100 lần thay vì 10 lần. Các bạn có thể tìm hiểu repo benchmark tại &lt;a href=&quot;https://github.com/nartc/ng-automapper-bench&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;đây&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;có-gì-mới&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#c%C3%B3-g%C3%AC-m%E1%BB%9Bi&quot; aria-label=&quot;có gì mới permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Có gì mới&lt;/h2&gt;
&lt;p&gt;Bản release v6 lần này không có quá nhiều sự thay đổi về mặt public API nhưng tối ưu hơn, nhỏ gọn hơn, một số bản sửa lỗi, và cung cấp một API mới để support &lt;strong&gt;JavaScript&lt;/strong&gt;. Nghe thật thú vị hen, khám phá cùng mình thôi 💪&lt;/p&gt;
&lt;h2 id=&quot;hiệu-năng&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#hi%E1%BB%87u-n%C4%83ng&quot; aria-label=&quot;hiệu năng permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Hiệu năng&lt;/h2&gt;
&lt;p&gt;Với những thư viện thiên về thay đổi hoặc biến hoá data như &lt;strong&gt;AutoMapper&lt;/strong&gt; thì vấn đề về hiệu năng đều khá quan trọng. Tuy nhiên trước khi đi quá sâu về vấn đề Hiệu năng,
mình muốn nhấn mạnh mục đích của &lt;strong&gt;AutoMapper&lt;/strong&gt; khi mình quyết định viết thư viện này chính là để transform &lt;strong&gt;Data Model (database)&lt;/strong&gt; sang &lt;strong&gt;View Model (client/frontend)&lt;/strong&gt;
nên số lượng phần tử không nhất thiết phải lên đến hàng trăm ngàn phần tử thông qua &lt;strong&gt;Network Call&lt;/strong&gt;. Với điều đó thì việc &lt;strong&gt;map&lt;/strong&gt; một tập lên đến hàng triệu phần tử thì
khá là không thực tế 😊. Bây giờ thì chúng ta nhìn vào 1 chút thông số nhé.&lt;/p&gt;
&lt;p&gt;Đầu tiên, đây là model &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; mà mình làm mẫu cho benchmark này:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;68107007283488260000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class Bio {
  job: string;
  age: number;
  birthday: Date;
}

class User {
  firstName: string;
  lastName: string;
  bio: Bio;
}`, `68107007283488260000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bio&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  age&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Bio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;và view model &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt; tương ứng:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;3659257185528663600&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class BioVm {
  job: string;
  isAdult: boolean;
  birthday: string;
}

class UserVm {
  first: string;
  last: string;
  full: string;
  bio: BioVm;
}`, `3659257185528663600`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BioVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  isAdult&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  first&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  last&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  full&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;với cấu hình như sau:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;29341900945193087000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`Mapper.createMap(User, UserVm)
  .forMember(
    (d) =&gt; d.first,
    mapFrom((s) =&gt; s.firstName)
  )
  .forMember(
    (d) =&gt; d.last,
    mapFrom((s) =&gt; s.lastName)
  )
  .forMember(
    (d) =&gt; d.full,
    mapFrom((s) =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
  );
Mapper.createMap(Bio, BioVm)
  .forMember(
    (d) =&gt; d.isAdult,
    mapFrom((s) =&gt; s.age &gt; 18)
  )
  .forMember(
    (d) =&gt; d.birthday,
    mapFrom((s) =&gt; s.birthday.toDateString())
  );`, `29341900945193087000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isAdult&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;birthday&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;birthday&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thực thi &lt;strong&gt;map&lt;/strong&gt; từ &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; sang &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt; với cấu hình trên lên 1K, 10K và 100K phần tử cho mình kết quả như sau:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;1K items&lt;/th&gt;
&lt;th&gt;10K items&lt;/th&gt;
&lt;th&gt;100K items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; v5&lt;/td&gt;
&lt;td&gt;~9ms&lt;/td&gt;
&lt;td&gt;~88ms&lt;/td&gt;
&lt;td&gt;~959ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; v6&lt;/td&gt;
&lt;td&gt;~8ms&lt;/td&gt;
&lt;td&gt;~81ms&lt;/td&gt;
&lt;td&gt;~785ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Mỗi benchmark được chạy ~10~ 100 lần cho mỗi 1K, 10K, và 100K phần tử rồi lấy trung bình 10 lần chạy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Các bạn có thể thấy rằng v6 nhanh hơn v5 khoảng 15-25%. Và cái gì thực sự thay đổi ở v6? &lt;strong&gt;AutoMapper&lt;/strong&gt; v6 đã áp dụng một số phương pháp sau để tăng hiệu năng:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Loops Optimization: v6 sử dụng &lt;code class=&quot;language-text&quot;&gt;while&lt;/code&gt; thay thế cho &lt;code class=&quot;language-text&quot;&gt;for let&lt;/code&gt; (original &lt;code class=&quot;language-text&quot;&gt;for&lt;/code&gt; loop với biến index) ở một số chỗ quan trọng như: &lt;strong&gt;map&lt;/strong&gt; và &lt;strong&gt;initialize mapping properties&lt;/strong&gt;.
Ở những khu vực &lt;code class=&quot;language-text&quot;&gt;for&lt;/code&gt; loop vẫn sử dụng thì biến &lt;code class=&quot;language-text&quot;&gt;length&lt;/code&gt; đã được cached để giảm thiểu &lt;code class=&quot;language-text&quot;&gt;property lookup&lt;/code&gt; ở mỗi vòng loop.&lt;/li&gt;
&lt;li&gt;Accessing Array Index: v6 chuyển phần lớn cấu trúc data mà phần &lt;code class=&quot;language-text&quot;&gt;core&lt;/code&gt; sử dụng từ dạng &lt;code class=&quot;language-text&quot;&gt;Object&lt;/code&gt; sang &lt;code class=&quot;language-text&quot;&gt;Array&lt;/code&gt; để giảm thiểu &lt;code class=&quot;language-text&quot;&gt;property lookup&lt;/code&gt;. Và vẫn còn nhiều chỗ để cải thiện ở vấn đề này trong &lt;strong&gt;AutoMapper&lt;/strong&gt; v6.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Tìm hiểu thêm về &lt;strong&gt;Accessing Array Index&lt;/strong&gt; từ talk &lt;a href=&quot;https://www.youtube.com/watch?v=EqSRpkMRyY4&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;How we make Angular fast&lt;/a&gt; của Misko Hevery&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Với sự cho phép của &lt;a href=&quot;https://twitter.com/YannRenaudin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Yann Renaudin&lt;/a&gt;, là tác giả của thư viện &lt;a href=&quot;https://github.com/nobrainr/morphism&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;morphism&lt;/a&gt;, mình xin chia sẻ benchmark của &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; với cấu hình tương tự như trên:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;93890759938473330000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const morphismSchema = {
  first: &amp;quot;firstName&amp;quot;,
  last: &amp;quot;lastName&amp;quot;,
  full: ({ firstName, lastName }) =&gt; firstName + &amp;quot; &amp;quot; + lastName,
  bio: {
    job: &amp;quot;bio.job&amp;quot;,
    isAdult: ({ bio }) =&gt; bio.age &gt; 18,
    birthday: ({ bio }) =&gt; bio.birthday.toDateString(),
  },
};`, `93890759938473330000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; morphismSchema &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  first&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;firstName&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  last&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lastName&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;full&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; lastName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bio.job&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;isAdult&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; bio &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; bio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;age &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function-variable function&quot;&gt;birthday&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; bio &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; bio&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;birthday&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toDateString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Mỗi benchmark được chạy ~10~ 100 lần cho mỗi 1K, 10K, và 100K phần tử rồi lấy trung bình 10 lần chạy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;1K items&lt;/th&gt;
&lt;th&gt;10K items&lt;/th&gt;
&lt;th&gt;100K items&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~15ms&lt;/td&gt;
&lt;td&gt;~144ms&lt;/td&gt;
&lt;td&gt;~1436ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;create-mapper&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;~15ms&lt;/td&gt;
&lt;td&gt;~145ms&lt;/td&gt;
&lt;td&gt;~1464ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; v6&lt;/td&gt;
&lt;td&gt;~8ms&lt;/td&gt;
&lt;td&gt;~81ms&lt;/td&gt;
&lt;td&gt;~785ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Đây chỉ là sự so sánh với 1 benchmark cực kỳ đơn giản và chỉ so sánh về khoản &lt;strong&gt;map&lt;/strong&gt; từ một model sang một model khác mà thôi. Về tiện ích, &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; là một thư viện cực kỳ tuyệt vời
nếu các bạn có nhu cầu. &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; hỗ trợ &lt;strong&gt;map&lt;/strong&gt; với &lt;code class=&quot;language-text&quot;&gt;schema configuration&lt;/code&gt; và điều này thì cực kỳ thích hợp với những dự án thuần &lt;strong&gt;JavaScript&lt;/strong&gt;, không có nhiều &lt;code class=&quot;language-text&quot;&gt;classes&lt;/code&gt; để tượng trưng
cho cấu trúc dữ liệu ở trong code. Nếu bạn có hứng thú thì có thể tìm hiểu thêm về &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; tại &lt;a href=&quot;https://github.com/nobrainr/morphism&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;đây&lt;/a&gt;. Cám ơn &lt;a href=&quot;https://twitter.com/YannRenaudin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Yann&lt;/a&gt; đã
cho phép mình lấy &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; làm benchmark cho &lt;strong&gt;AutoMapper&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;nhỏ-gọn&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#nh%E1%BB%8F-g%E1%BB%8Dn&quot; aria-label=&quot;nhỏ gọn permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Nhỏ gọn&lt;/h2&gt;
&lt;p&gt;Nhìn chung, kích thước thư viện của v6 nhỏ hơn v5. Các hàm tiện ích (Utility Function) và phần &lt;code class=&quot;language-text&quot;&gt;core&lt;/code&gt; của thư viện đã được “dọn dẹp” khá nhiều.
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 431px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0954430092f37881645b1e54b07aecfc/369db/master.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABP0lEQVQoz61STU+DQBDl39cm/AoTYj20iQeNHjTBG7fyC5pILRTYLbVQvnnujEK3sUYOTvIyZHg7++bNGrgQXdfhr/iNY/Q/KPegqKqakRcF56ZpUFYViqLkb/3MxYZt2w6gCCPBeFtvOO+SPbZhjPUmwCHNqN0PEZSNsSOOtWBQuFwuYds2XNflEbdhhLquB/UUQRDAcRz4vq/4Lmo1ehjFyoL2pLAnW5aF6XQK0zRx//SC65s5k/WGq9UKi8UCt7MZJpMrPD6/Yn73ACF3p4a9Qs/zIKWEFAL7jwOiWLBSfZyyLJFlmULK3ET5KnfJuYe6f/42RCwkZ9qm3ixQNT8IeUFCJqiUHcSlRb2rRaW8KM1D8iM7HvmZUKYnojcsVD3Pe+TK3y8+XUy16ttvA/8cBinKz27XUGjIR0DxPgF/tVKuDdcLPAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;master&quot;
        title=&quot;master&quot;
        src=&quot;/static/0954430092f37881645b1e54b07aecfc/369db/master.png&quot;
        srcset=&quot;/static/0954430092f37881645b1e54b07aecfc/7b64c/master.png 160w,
/static/0954430092f37881645b1e54b07aecfc/4e610/master.png 320w,
/static/0954430092f37881645b1e54b07aecfc/369db/master.png 431w&quot;
        sizes=&quot;(max-width: 431px) 100vw, 431px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Kích thước của AutoMapper v5&lt;/em&gt;
&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 433px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b479a1493e757b87949f625d23c11a31/293b3/next.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 53.125%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAABXklEQVQoz41SS0/CQBDmRxM8ceOXcIaLHGyqWIOahmhKJRAPxBgjfdDS8ixtabefu4sL2NLESSY7O/vNt/Oq4IJkWXY8hV2GyUvlv0BBnv8kj+eEhBCuJ3AGf7GEO/fxbViwHRer9Yb7LNvhp4g7r+ZihkLiOEYYRQcNI8T7PdcoigvYc+IKM2zbhuM48DwPSZLAMIyyf2gggWmanICdaZr+KZ9n2Gq10Gg00Gw2Icsy6vU6+q8D3Nwq+Pj84mAROB6PUa1WMZlMcFWrQZLvcN9T0XvunzKUJAndbheKokDTNH4fvI3w8KhialrHspiwKjqda+i6jna7jYE+xJP6guHo/UQoJKT94b2K9xcnyfq5DXa0LSm3xRvD78IQm21wIBTOKZ2oO/d4VqvVurCLS+ozrRnsmUOnPaPkATx/Qe8uLOpjsaVTzu9Y2X4WFltkQJj+7mN+L4+Y3DshRd8PnwdMZHbMDMsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;next&quot;
        title=&quot;next&quot;
        src=&quot;/static/b479a1493e757b87949f625d23c11a31/293b3/next.png&quot;
        srcset=&quot;/static/b479a1493e757b87949f625d23c11a31/7b64c/next.png 160w,
/static/b479a1493e757b87949f625d23c11a31/4e610/next.png 320w,
/static/b479a1493e757b87949f625d23c11a31/293b3/next.png 433w&quot;
        sizes=&quot;(max-width: 433px) 100vw, 433px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Kích thước của AutoMapper v6&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Kích thước bundle được cung cấp bởi &lt;a href=&quot;https://bundlephobia.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Bundlephobia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mặt khác, hãy nhìn qua lại cấu hình &lt;strong&gt;mapping&lt;/strong&gt; khi nãy với sự khác nhau giữa v5 và v6:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;5896944713337215000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// v5
Mapper.createMap(User, UserVm)
  .forMember(
    (d) =&gt; d.first,
    (opts) =&gt; opts.mapFrom((s) =&gt; s.firstName)
  )
  .forMember(
    (d) =&gt; d.last,
    (opts) =&gt; opts.mapFrom((s) =&gt; s.lastName)
  )
  .forMember(
    (d) =&gt; d.full,
    (opts) =&gt; opts.mapFrom((s) =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
  );

// v6
Mapper.createMap(User, UserVm)
  .forMember(
    (d) =&gt; d.first,
    mapFrom((s) =&gt; s.firstName)
  )
  .forMember(
    (d) =&gt; d.last,
    mapFrom((s) =&gt; s.lastName)
  )
  .forMember(
    (d) =&gt; d.full,
    mapFrom((s) =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
  );`, `5896944713337215000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// v5&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// v6&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Các bạn có thấy sự khác biệt không? Ở v6, tham số thứ 2 của hàm &lt;code class=&quot;language-text&quot;&gt;forMember()&lt;/code&gt; không còn lại &lt;code class=&quot;language-text&quot;&gt;ForMemberOptions&lt;/code&gt; nữa.
&lt;code class=&quot;language-text&quot;&gt;ForMemberOptions&lt;/code&gt; là 1 &lt;code class=&quot;language-text&quot;&gt;Function Interface&lt;/code&gt; chứa tất cả các hàm &lt;strong&gt;mapping operations&lt;/strong&gt; như: &lt;code class=&quot;language-text&quot;&gt;mapFrom()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;mapWith()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;ignore()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;condition()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;fromValue()&lt;/code&gt;, và một số hàm khác nữa.
Ở v6, tất cả các hàm &lt;strong&gt;mapping operations&lt;/strong&gt; này đều được tách riêng ra thành những &lt;code class=&quot;language-text&quot;&gt;Pure Function&lt;/code&gt; riêng biệt. Điều này giúp cho &lt;strong&gt;AutoMapper&lt;/strong&gt; v6 có thể &lt;code class=&quot;language-text&quot;&gt;tree-shakable&lt;/code&gt; được.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;tree-shake&lt;/code&gt; là thuật ngữ ở bước Bundle/Build code, dùng để chỉ đến việc những code không sử dụng đến (ví dụ như hàm được khai báo, nhưng không sử dụng đến trong code) thì sẽ được Builder/Bundler xoá sổ khỏi bundle cuối cùng. Kết quả là kích thước bundle cuối cùng có thể sẽ rất nhỏ, nhờ giảm đi được những code không dùng đến.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;lỗi-this-lỗi-that&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#l%E1%BB%97i-this-l%E1%BB%97i-that&quot; aria-label=&quot;lỗi this lỗi that permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Lỗi this lỗi that&lt;/h2&gt;
&lt;p&gt;Ở những version trước của &lt;strong&gt;AutoMapper&lt;/strong&gt;, các &lt;strong&gt;Mapping&lt;/strong&gt; và &lt;strong&gt;Profile&lt;/strong&gt; được lưu trữ dưới dạng là &lt;code class=&quot;language-text&quot;&gt;Object&lt;/code&gt; và dùng biến &lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt; ở trên các &lt;code class=&quot;language-text&quot;&gt;Class&lt;/code&gt; này để làm &lt;code class=&quot;language-text&quot;&gt;key&lt;/code&gt; cho các item này. Và chuyện gì đến sẽ đến, cái gì cũng đúng cho đến khi nó sai🤦‍,
những &lt;code class=&quot;language-text&quot;&gt;Object&lt;/code&gt; này vì dùng &lt;code class=&quot;language-text&quot;&gt;Class.name&lt;/code&gt; nên khi người sử dụng thư viện (consumer) chạy code cho môi trường production, các plugins làm gọn code như &lt;strong&gt;Uglify&lt;/strong&gt; hoặc &lt;strong&gt;Terser&lt;/strong&gt; sẽ làm cho các &lt;code class=&quot;language-text&quot;&gt;Class.name&lt;/code&gt; này bị trùng.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AutoMapper&lt;/strong&gt; v6 đã thay đổi cách lưu trữ những dữ liệu này với các &lt;strong&gt;Storages&lt;/strong&gt;. Những storages này dùng &lt;code class=&quot;language-text&quot;&gt;WeakMap&lt;/code&gt; để lưu trữ chính &lt;code class=&quot;language-text&quot;&gt;Class&lt;/code&gt; làm &lt;code class=&quot;language-text&quot;&gt;key&lt;/code&gt; thay vì dùng &lt;code class=&quot;language-text&quot;&gt;Class.name&lt;/code&gt;. Điều này đảm bảo các &lt;code class=&quot;language-text&quot;&gt;Class&lt;/code&gt;
sẽ không bị trùng nhau cho dù đã được &lt;strong&gt;minified&lt;/strong&gt;.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;839792052035015600&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Để thấy được vấn đề với Class.name
class Foo {}

console.log(Foo.name); // logs Foo
console.log(Foo.prototype.constructor.name); // logs Foo`, `839792052035015600`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Để thấy được vấn đề với Class.name&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Foo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// logs Foo&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// logs Foo&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;hỗ-trợ-javascript&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#h%E1%BB%97-tr%E1%BB%A3-javascript&quot; aria-label=&quot;hỗ trợ javascript permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Hỗ trợ JavaScript&lt;/h2&gt;
&lt;p&gt;Trước v6, hỗ trợ cho &lt;strong&gt;JavaScript&lt;/strong&gt; hầu như là không tồn tại. &lt;strong&gt;AutoMapper&lt;/strong&gt; chỉ hoạt động với những dự án &lt;strong&gt;TypeScript&lt;/strong&gt; mà thôi. Ở v6, &lt;strong&gt;AutoMapper&lt;/strong&gt; sẽ cung cấp một API để hỗ trợ cho &lt;strong&gt;JavaScript&lt;/strong&gt;.
Trước khi giới thiệu qua API này, mình xin nói sơ qua về cách hoạt động của &lt;strong&gt;AutoMapper&lt;/strong&gt; để mọi người hiểu rõ hơn về việc “chỉ hỗ trợ TypeScript”.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AutoMapper&lt;/strong&gt; hoạt động theo nguyên lý lưu trữ &lt;strong&gt;Metadata&lt;/strong&gt; (data về data) của các Models. Ví dụ model &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; ở trên có: &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; là &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt; là &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt;, và &lt;code class=&quot;language-text&quot;&gt;bio&lt;/code&gt; là model &lt;code class=&quot;language-text&quot;&gt;Bio&lt;/code&gt;. Đây
được gọi là &lt;strong&gt;Metadata&lt;/strong&gt; của class &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt;. Để có được thông tin của những &lt;strong&gt;metadata&lt;/strong&gt; này tại runtime, &lt;strong&gt;AutoMapper&lt;/strong&gt; dùng decorator &lt;code class=&quot;language-text&quot;&gt;@AutoMap()&lt;/code&gt;. Sau đó, &lt;code class=&quot;language-text&quot;&gt;MetadataStorage&lt;/code&gt; sẽ đảm nhiệm việc lưu trữ
&lt;strong&gt;metadata&lt;/strong&gt; mà &lt;code class=&quot;language-text&quot;&gt;@AutoMap()&lt;/code&gt; cung cấp. Ở những dự án &lt;strong&gt;JavaScript&lt;/strong&gt; thì việc sử dụng &lt;code class=&quot;language-text&quot;&gt;decorator&lt;/code&gt; là khá phức tạp, và bản thân &lt;strong&gt;AutoMapper&lt;/strong&gt; cũng không cung cấp một API nào để làm việc với &lt;strong&gt;JavaScript&lt;/strong&gt;. Nhưng điều này sẽ thay đổi ở &lt;strong&gt;AutoMapper&lt;/strong&gt; v6.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AutoMapper&lt;/strong&gt; v6 sẽ cung cấp API có tên là: &lt;code class=&quot;language-text&quot;&gt;createMapMetadata&lt;/code&gt;. API này sẽ “giả lập” cách hoạt động của &lt;code class=&quot;language-text&quot;&gt;@AutoMap()&lt;/code&gt; để có thể lưu trữ được &lt;strong&gt;metadata&lt;/strong&gt;. Tuy nhiên, API này vẫn yêu cầu consumers cung cấp
một số boiler-plate nhất định.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;80378343299376300000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class User {}
class UserVm {}

class Bio {}
class BioVm {}`, `80378343299376300000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Bio&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BioVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;JavaScript&lt;/strong&gt; không có khai báo &lt;code class=&quot;language-text&quot;&gt;fields&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;types&lt;/code&gt; nên có thể để trống. Nhưng những &lt;code class=&quot;language-text&quot;&gt;class&lt;/code&gt; trống này bắt buộc phải có, vì lý do lưu trữ &lt;strong&gt;Mapping&lt;/strong&gt; mình đề cập tới ở mục trên.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;24357205011660943000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`createMapMetadata(Bio, {
  job: String,
  age: Number,
  birthday: Date,
});
createMapMetadata(User, {
  firstName: String,
  lastName: String,
  bio: Bio,
});
createMapMetadata(BioVm, {
  job: String,
  isAdult: Boolean,
  birthday: String,
});
createMapMetadata(UserVm, {
  first: String,
  last: String,
  full: String,
  bio: BioVm,
});`, `24357205011660943000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  age&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Number&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  isAdult&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Boolean&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  first&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  last&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  full&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Khá dài dòng đúng không? Thực sự ra thì consumer không cần phải khai báo toàn bộ các &lt;code class=&quot;language-text&quot;&gt;fields&lt;/code&gt; như trên, mà chỉ cần khai báo các &lt;code class=&quot;language-text&quot;&gt;fields&lt;/code&gt; nào mà &lt;strong&gt;SẼ KHÔNG&lt;/strong&gt; được cấu hình bằng &lt;code class=&quot;language-text&quot;&gt;.forMember()&lt;/code&gt;.
Theo như cấu hình &lt;strong&gt;mapping&lt;/strong&gt; ở đầu bài blog, thì &lt;code class=&quot;language-text&quot;&gt;isAdult&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;birthday&lt;/code&gt; ở &lt;code class=&quot;language-text&quot;&gt;BioVm&lt;/code&gt; là không cần khai báo. Tương tự, &lt;code class=&quot;language-text&quot;&gt;first&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;last&lt;/code&gt;, và &lt;code class=&quot;language-text&quot;&gt;full&lt;/code&gt; ở &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt; cũng không cần khai báo. Code sẽ như thế này:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;22550078876279710000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`createMapMetadata(Bio, {
  job: String,
  age: Number,
  birthday: Date,
});
createMapMetadata(User, {
  firstName: String,
  lastName: String,
  bio: Bio,
});

createMapMetadata(BioVm, {
  job: String,
});
createMapMetadata(UserVm, {
  bio: BioVm,
});`, `22550078876279710000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  age&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Number&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  birthday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Bio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  job&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createMapMetadata&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BioVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Điều tương tự sẽ được áp dụng khi consumer cấu hình từ &lt;code class=&quot;language-text&quot;&gt;UserVm -&amp;gt; User&lt;/code&gt; (&lt;code class=&quot;language-text&quot;&gt;BioVm -&amp;gt; Bio&lt;/code&gt;) thì những &lt;code class=&quot;language-text&quot;&gt;fields&lt;/code&gt; nào &lt;strong&gt;SẼ ĐƯỢC&lt;/strong&gt; cấu hình bằng &lt;code class=&quot;language-text&quot;&gt;.forPath()&lt;/code&gt; (nếu dùng &lt;code class=&quot;language-text&quot;&gt;reverseMap()&lt;/code&gt;) hoặc &lt;code class=&quot;language-text&quot;&gt;.forMember()&lt;/code&gt; thì không cần khai báo ở &lt;code class=&quot;language-text&quot;&gt;createMapMetadata()&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&quot;cài-đặt&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#c%C3%A0i-%C4%91%E1%BA%B7t&quot; aria-label=&quot;cài đặt permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cài đặt&lt;/h2&gt;
&lt;p&gt;Các bạn có thể sử dụng qua bản &lt;code class=&quot;language-text&quot;&gt;next&lt;/code&gt; của &lt;strong&gt;AutoMapper&lt;/strong&gt; bằng cách sau:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;npm i @nartc/automapper@next&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;thay-đổi-từ-v5&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#thay-%C4%91%E1%BB%95i-t%E1%BB%AB-v5&quot; aria-label=&quot;thay đổi từ v5 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Thay đổi từ v5&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Như mình đã đề cập ở trên, các hàm &lt;strong&gt;mapping operations&lt;/strong&gt; đã được tách ra thành hàm riêng, cấu hình &lt;strong&gt;mapping&lt;/strong&gt; có thay đổi như sau:&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;39539296381027290000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// before
Mapper.createMap(User, UserVm)
    .forMember(d =&gt; d.full, opts =&gt; opts.mapFrom(s =&gt; s.first + &apos; &apos; + s.last)
    .forMember(d =&gt; d.foo, opts =&gt; opts.ignore());

// after
Mapper.createMap(User, UserVm)
    .forMember(d =&gt; d.full, mapFrom(s =&gt; s.first + &apos; &apos; + s.last)
    .forMember(d =&gt; d.foo, ignore())`, `39539296381027290000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// before&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// after&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;full&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ignore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Mapper.initialize()&lt;/code&gt; đã được khai tử. Các bạn nên dùng thẳng: &lt;code class=&quot;language-text&quot;&gt;Mapper.createMap()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Mapper.addProfile()&lt;/code&gt;, và &lt;code class=&quot;language-text&quot;&gt;Mapper.withGlobalSettings()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Tất cả các tham số nhận &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;NamingConvention&lt;/code&gt; đều sẽ nhận vào &lt;code class=&quot;language-text&quot;&gt;Class&lt;/code&gt; của &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;NamingConvention&lt;/code&gt; đó thay vì 1 &lt;code class=&quot;language-text&quot;&gt;instance&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;24420619790092067000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// before
Mapper.createMap(User, UserVm, {
  sourceMemberNamingConvention: new PascalCaseNamingConvention(),
});

// after
Mapper.createMap(User, UserVm, {
  sourceMemberNamingConvention: PascalCaseNamingConvention,
});`, `24420619790092067000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// before&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sourceMemberNamingConvention&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PascalCaseNamingConvention&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// after&lt;/span&gt;
Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sourceMemberNamingConvention&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PascalCaseNamingConvention&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Các bạn có thể tìm hiểu thêm tại &lt;a href=&quot;https://automapper.netlify.com/docs/next/introduction/why&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;đây&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;kết-bài&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#k%E1%BA%BFt-b%C3%A0i&quot; aria-label=&quot;kết bài permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Kết bài&lt;/h2&gt;
&lt;p&gt;Một lần nữa, mình cảm thấy rất phấn khởi khi được giới thiệu với các bạn về những thay đổi của &lt;strong&gt;AutoMapper&lt;/strong&gt; v6. Cũng như những bài blog về &lt;strong&gt;AutoMapper&lt;/strong&gt; mình từng viết, hy vọng
mọi người sẽ tham khảo qua và sử dụng thử nếu cảm thấy thích hợp với các use-cases của dự án của các bạn. Cám ơn mọi người đã đọc bài blog và hẹn gặp lại trong bài blog kế tiếp 👋&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Build Dynamic Dialog with Angular CDK]]></title><description><![CDATA[Angular CDK is short for Angular Component Dev Kit (CDK). As the name suggests, the CDK provides you a set of tools to build feature-packed…]]></description><link>https://nartc.netlify.com/blogs/build-dynamic-dialog-angular-cdk/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/build-dynamic-dialog-angular-cdk/</guid><pubDate>Wed, 08 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Angular CDK&lt;/strong&gt; is short for &lt;strong&gt;Angular Component Dev Kit (CDK)&lt;/strong&gt;. As the name suggests, the CDK provides you a set of tools to build feature-packed and high-quality &lt;strong&gt;Angular&lt;/strong&gt; components without having to adhere to &lt;strong&gt;Material Design&lt;/strong&gt; that &lt;strong&gt;Google&lt;/strong&gt; embraces. The goal of the CDK is to allow developers to easier implement &lt;em&gt;Common Patterns and Behaviors&lt;/em&gt; in our &lt;strong&gt;Angular&lt;/strong&gt; applications. There are many different packages, patterns, and behaviors that you can explore by checking out the CDK &lt;a href=&quot;https://material.angular.io/cdk/categories&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;documentation&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Lately, I have been involving in an &lt;strong&gt;Angular&lt;/strong&gt; project where we have multiple &lt;strong&gt;UI Component Suite&lt;/strong&gt; installed like &lt;code class=&quot;language-text&quot;&gt;NgBootstrap&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;PrimeNG&lt;/code&gt;, and couple other miscellaneous packages. Though these packages get the job done (and quick), we are at the point of having too many different moving parts to maintain and keep up-to-date. In other words, &lt;strong&gt;tech debts&lt;/strong&gt; are building up and &lt;strong&gt;inconsistency&lt;/strong&gt; is haunting our project. One prime example is &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; usage where you can a &lt;strong&gt;Dialog&lt;/strong&gt; and pass in a custom &lt;strong&gt;Component&lt;/strong&gt; as the content of the &lt;strong&gt;Dialog&lt;/strong&gt; with extra data. Sounds neat right? At the moment we needed the feature, &lt;code class=&quot;language-text&quot;&gt;PrimeNG&lt;/code&gt; didn’t have support for &lt;strong&gt;DynamicDialog&lt;/strong&gt; (they do now, check it out at &lt;a href=&quot;https://www.primefaces.org/primeng/#/dynamicdialog&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;PrimeNG DynamicDialog&lt;/a&gt;). One of our developers turned to &lt;code class=&quot;language-text&quot;&gt;NgBootstrap&lt;/code&gt; for their &lt;strong&gt;NgbModal&lt;/strong&gt; (&lt;a href=&quot;https://ng-bootstrap.github.io/#/components/modal/examples&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;NgBootstrap NgbModal&lt;/a&gt;). That’s when we ended up with both &lt;code class=&quot;language-text&quot;&gt;NgBootstrap&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;PrimeNG&lt;/code&gt; in our project.&lt;/p&gt;
&lt;p&gt;Now, we have turned ourselves to these different libraries for just a usage of a &lt;strong&gt;Dialog&lt;/strong&gt;. There has to be a better way which is already available to you right? Luckily, yes. &lt;strong&gt;Angular CDK&lt;/strong&gt; does provide an “easy” way to implement your own &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; with &lt;strong&gt;ANY&lt;/strong&gt; stylings you want to go with. I have been looking into the &lt;strong&gt;Angular CDK&lt;/strong&gt;, namely the &lt;strong&gt;Overlay&lt;/strong&gt; module, to explore a way to build &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; without any dependency to those &lt;strong&gt;UI Component Suite&lt;/strong&gt; so we will not have to rely on those &lt;strong&gt;Suite&lt;/strong&gt; for future projects. This blog post is a mean to share my findings with you all and we are going to utilize &lt;strong&gt;Angular CDK OverlayModule&lt;/strong&gt; along with &lt;strong&gt;BulmaCSS&lt;/strong&gt; to build a &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; that adheres to &lt;strong&gt;Angular&lt;/strong&gt; convention and not look like &lt;strong&gt;Material Design.&lt;/strong&gt; Let’s jump it.&lt;/p&gt;
&lt;h3 id=&quot;preparations&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#preparations&quot; aria-label=&quot;preparations permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Preparations&lt;/h3&gt;
&lt;p&gt;Go ahead and initialize a new &lt;strong&gt;Angular&lt;/strong&gt; application using the &lt;strong&gt;Angular CLI&lt;/strong&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;61477818142388680000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng new cdk-bulma-dialog`, `61477818142388680000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng new cdk-bulma-dialog&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;If you haven’t installed &lt;strong&gt;Angular CLI&lt;/strong&gt;, let’s do so with &lt;code class=&quot;language-text&quot;&gt;npm i -g @angular/cli&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5bcc501ef0375ed4ebe214027cc68ee9/6150a/ngcli.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsSAAALEgHS3X78AAABEklEQVQY02WP226CUBBF+ZZar4jFqihwuLfKTSuYWnixGPv/v7B6wDRN04eVmT3ZM5mt5FlNnGak+5gs35PvDxzejhyLgjTLsYWDH4SYtmCxXGFsNnfWLet/KEVZcLt9UdUffF4unM9nrteGpmm4SF2WJXVdsU0SHMdhMhnT6z3QHwwYDId/GI3HKOEuxo1eeHpe4G13bFwPIbXp+V0NkhQ/TggkUZrjSo+3S1jLz3VdR5/P78h9VZ2i+GHINo5lJJv3qiKTkU/yy+Pp1PWBPOpHEY4fIDwPNwgIXl4RrosQAkvu2W2VTFQVxTAMbDlcrladYWOanaGdWZaFpmk89vu/0WTUn7jD0aij7bXZDHU65Rvw36t7X1bLJwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ngcli&quot;
        title=&quot;ngcli&quot;
        src=&quot;/static/5bcc501ef0375ed4ebe214027cc68ee9/1bed9/ngcli.png&quot;
        srcset=&quot;/static/5bcc501ef0375ed4ebe214027cc68ee9/7b64c/ngcli.png 160w,
/static/5bcc501ef0375ed4ebe214027cc68ee9/4e610/ngcli.png 320w,
/static/5bcc501ef0375ed4ebe214027cc68ee9/1bed9/ngcli.png 640w,
/static/5bcc501ef0375ed4ebe214027cc68ee9/6150a/ngcli.png 651w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Angular CLI generating new Angular application&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We are &lt;strong&gt;not&lt;/strong&gt; going to need &lt;code class=&quot;language-text&quot;&gt;routing&lt;/code&gt; and let’s also pick &lt;code class=&quot;language-text&quot;&gt;SCSS&lt;/code&gt; for our stylings. Next, let’s install &lt;strong&gt;Angular CDK&lt;/strong&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;47318218335997850000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng add @angular/cdk`, `47318218335997850000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng add @angular/cdk&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open &lt;code class=&quot;language-text&quot;&gt;styles.scss&lt;/code&gt; and add this line:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;95148848889200970000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`@import &apos;~@angular/cdk/overlay-prebuilt.css&apos;;`, `95148848889200970000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;scss&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-scss line-numbers&quot;&gt;&lt;code class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~@angular/cdk/overlay-prebuilt.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt; and add &lt;code class=&quot;language-text&quot;&gt;BrowserAnimationsModule&lt;/code&gt; import:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;63095906109426950000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { NgModule } from &apos;@angular/core&apos;;
import { BrowserModule } from &apos;@angular/platform-browser&apos;;
import { BrowserAnimationsModule } from &apos;@angular/platform-browser/animations&apos;; // &lt;-- add this import
import { AppComponent } from &apos;./app.component&apos;;

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, BrowserAnimationsModule], // &lt;-- add BrowserAnimationsModule
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}`, `63095906109426950000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserAnimationsModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- add this import&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AppComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BrowserModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BrowserAnimationsModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- add BrowserAnimationsModule&lt;/span&gt;
  providers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bootstrap&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open &lt;code class=&quot;language-text&quot;&gt;index.html&lt;/code&gt; and edit as following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;62448064481047000000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;!doctype html&gt;
&lt;html lang=&amp;quot;en&amp;quot;&gt;
&lt;head&gt;
  &lt;meta charset=&amp;quot;utf-8&amp;quot;&gt;
  &lt;title&gt;CdkBulmaDialog&lt;/title&gt;
  &lt;base href=&amp;quot;/&amp;quot;&gt;
  &lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1&amp;quot;&gt;
  &lt;link rel=&amp;quot;icon&amp;quot; type=&amp;quot;image/x-icon&amp;quot; href=&amp;quot;favicon.ico&amp;quot;&gt;
    &lt;!-- Add BulmaCSS CDN --&gt;
  &lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css&amp;quot;&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;app-root&gt;&lt;/app-root&gt;
&lt;/body&gt;
&lt;/html&gt;`, `62448064481047000000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&amp;lt;!doctype html&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;en&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;utf-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;CdkBulmaDialog&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;base&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;viewport&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;width=device-width, initial-scale=1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;icon&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image/x-icon&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;favicon.ico&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Add BulmaCSS CDN --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;app-root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;app-root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we are ready to move on to the main content of this blog.&lt;/p&gt;
&lt;h3 id=&quot;more-files&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#more-files&quot; aria-label=&quot;more files permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;More Files&lt;/h3&gt;
&lt;p&gt;We are going to start off by generating and creating all of the files we are going to need.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Using &lt;strong&gt;Angular CLI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Generate &lt;code class=&quot;language-text&quot;&gt;DynamicDialogModule&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;61453767140497790000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate module dynamic-dialog`, `61453767140497790000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate module dynamic-dialog&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Generate &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;17781744038468372000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate service dynamic-dialog/dynamic-dialog --skipTests`, `17781744038468372000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate service dynamic-dialog/dynamic-dialog --skipTests&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;For brevity of this blog post, I am going to include &lt;code class=&quot;language-text&quot;&gt;skipTests&lt;/code&gt; flag in all &lt;code class=&quot;language-text&quot;&gt;ng generate&lt;/code&gt; commands.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Generate &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;25794809370117177000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate directive dynamic-dialog/dynamic-dialog-content --skipTests`, `25794809370117177000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate directive dynamic-dialog/dynamic-dialog-content --skipTests&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Generate &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;18637214756216490000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate component dynamic-dialog/dynamic-dialog-root --flat --skipTests --inlineTemplate --inlineStyle`, `18637214756216490000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate component dynamic-dialog/dynamic-dialog-root --flat --skipTests --inlineTemplate --inlineStyle&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;We are going to use &lt;code class=&quot;language-text&quot;&gt;inlineTemplate&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;inlineStyle&lt;/code&gt; here so we keep everything that’s happening in our component in one &lt;code class=&quot;language-text&quot;&gt;*.component.ts&lt;/code&gt; file.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Creating directories and files&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We are going to need some &lt;strong&gt;Models&lt;/strong&gt; so go ahead and create a &lt;code class=&quot;language-text&quot;&gt;models&lt;/code&gt; directory under &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog&lt;/code&gt;. &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;78215226916952440000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`# assuming you are currently at the root of the project which is cdk-bulma-dialog
cd src/app/dynamic-dialog
mkdir models
cd models`, `78215226916952440000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;# assuming you are currently at the root of the project which is cdk-bulma-dialog
cd src/app/dynamic-dialog
mkdir models
cd models&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, let’s create couple files&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;33953198635270287000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`touch animation-state.enum.ts
touch dynamic-dialog-config.model.ts`, `33953198635270287000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;touch animation-state.enum.ts
touch dynamic-dialog-config.model.ts&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;and let’s also fill out these two new files. Open up &lt;code class=&quot;language-text&quot;&gt;animation-state.enum.ts&lt;/code&gt; &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;49755375567722340000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export enum AnimationState {
  Void = &apos;void&apos;,
  Enter = &apos;enter&apos;,
  Leave = &apos;leave&apos;
}`, `49755375567722340000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Void &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;void&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Enter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Leave &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;leave&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-config.model.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;26042936870146073000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { OverlayConfig } from &apos;@angular/cdk/overlay&apos;;

export class DynamicDialogConfig&lt;TData = any&gt; {
  header: string;
  closable: boolean;
  containerAnimationTiming: number;
  contentAnimationTiming: number;
  animationChildDelay: number;
  data?: TData;
  overlayConfig?: OverlayConfig;

  constructor() {
    this.header = &apos;&apos;;
    this.closable = true;
    this.containerAnimationTiming = 0.3;
    this.contentAnimationTiming = 0.2;
    this.animationChildDelay = 0;
  }
}`, `26042936870146073000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; OverlayConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  header&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  closable&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  containerAnimationTiming&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  contentAnimationTiming&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  animationChildDelay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  data&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; TData&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  overlayConfig&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;header &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;closable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;containerAnimationTiming &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentAnimationTiming &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationChildDelay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s go through each &lt;code class=&quot;language-text&quot;&gt;config&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt;: Very self-explanatory. We are going to configure our &lt;code class=&quot;language-text&quot;&gt;dialog&lt;/code&gt; to have a &lt;code class=&quot;language-text&quot;&gt;header title&lt;/code&gt;. We will allow the &lt;strong&gt;Dialog&lt;/strong&gt; consumers to be able to configure the &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt; through &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;closable&lt;/code&gt;: Whether to allow the &lt;strong&gt;Dialog&lt;/strong&gt; to be closed via: &lt;code class=&quot;language-text&quot;&gt;clicking on backdrop&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;clicking a close icon&lt;/code&gt;. By default, we would like to have a &lt;code class=&quot;language-text&quot;&gt;close icon&lt;/code&gt; on the right-hand side of the &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;containerAnimationTiming&lt;/code&gt;: How long the animation of the &lt;strong&gt;Dialog Container&lt;/strong&gt; runs. Visually, this is a fullscreen container underneath the &lt;strong&gt;Dialog Content&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;contentAnimationTiming&lt;/code&gt;: How long the actual &lt;strong&gt;Dialog Content&lt;/strong&gt; animation needs to run.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;animationChildDelay&lt;/code&gt;: How long the delay is between the &lt;code class=&quot;language-text&quot;&gt;containerAnimation&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;contentAnimation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt;: Extra data that we want to pass to the &lt;strong&gt;Dialog&lt;/strong&gt;. Most of the times, it could be some metadata like &lt;code class=&quot;language-text&quot;&gt;productId&lt;/code&gt; or something like that that we need to fetch required data to display in the &lt;strong&gt;Dialog&lt;/strong&gt;. The type is a &lt;strong&gt;Generic Type&lt;/strong&gt; which we can specify when we construct our &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; for a specific &lt;strong&gt;Dialog&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;overlayConfig&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; pass-through. The &lt;strong&gt;Dialog&lt;/strong&gt; that we are building will dictate some default &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt;  (from &lt;code class=&quot;language-text&quot;&gt;OverlayModule&lt;/code&gt;) but we will also allow the consumers to configure the &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; and merge it with our default setup should they desire to.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, the last thing we are going to need is &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;. I will explain the significant of this &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt; when we get to fill it out. For now, let’s create the file&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;90764955617594030000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`# assume you are in src/app/dynamic-dialog/models
cd ..
touch dynamic-dialog-ref.ts`, `90764955617594030000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;# assume you are in src/app/dynamic-dialog/models
cd ..
touch dynamic-dialog-ref.ts&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;lets-start-building&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#lets-start-building&quot; aria-label=&quot;lets start building permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Let’s start building&lt;/h3&gt;
&lt;p&gt;First, we are going to take care of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; as it is very short and straightforward. Open up &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-content.directive.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;29622322478264127000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Directive, ViewContainerRef } from &apos;@angular/core&apos;;

@Directive({
  selector: &apos;[appDynamicDialogContent]&apos;
})
export class DynamicDialogContentDirective {

  constructor(public readonly viewContainerRef: ViewContainerRef) { } // &lt;-- inject ViewContainerRef

}`, `29622322478264127000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ViewContainerRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[appDynamicDialogContent]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogContentDirective&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; viewContainerRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ViewContainerRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- inject ViewContainerRef&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; will play as the &lt;strong&gt;insertion point.&lt;/strong&gt; This is where we want to render our &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt; (as a &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt;) dynamically. Hence, we are going to inject &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; to the &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; and as the &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; is mounted, it will have access to the &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; of the element that the &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; is used on (Read more about &lt;a href=&quot;https://angular.io/api/core/Directive&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular Directive&lt;/a&gt;) Don’t worry, we will piece everything together soon enough.&lt;/p&gt;
&lt;p&gt;And that’s all we needed for &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;. Let’s open up &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-ref.ts&lt;/code&gt; and add this piece of code&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;10757251155282899000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export class DynamicDialogRef&lt;TReturnType = any&gt; {

}`, `10757251155282899000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s it for now. Open &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-root.component.ts&lt;/code&gt; now&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;3925711109342589000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy } from &apos;@angular/core&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;p&gt;
      dynamic-dialog-root works!
    &lt;/p&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush // &lt;-- also use OnPush strategy.
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy { // &lt;-- implements AfterViewInit and OnDestrou

  constructor() {
  }

  ngAfterViewInit(): void { // &lt;-- ngAfterViewInit implementation
  }

  ngOnDestroy(): void { // &lt;-- ngOnDestroy implementation
  }
}`, `3925711109342589000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;p&gt;
      dynamic-dialog-root works!
    &amp;lt;/p&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- also use OnPush strategy.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- implements AfterViewInit and OnDestrou&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- ngAfterViewInit implementation&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- ngOnDestroy implementation&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We are going to need a couple of fields:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;animationState&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt;: To keep track of animations of the &lt;code class=&quot;language-text&quot;&gt;container&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt; part of the &lt;strong&gt;Dialog&lt;/strong&gt;. We will base on the &lt;code class=&quot;language-text&quot;&gt;animationState&lt;/code&gt;  and &lt;code class=&quot;language-text&quot;&gt;AnimationEvent&lt;/code&gt; from &lt;code class=&quot;language-text&quot;&gt;@angular/animations&lt;/code&gt; to make meaningful decision about when the &lt;strong&gt;Dialog&lt;/strong&gt; is actually closed.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt;: Type of the &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; that is used for the &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt; of the &lt;strong&gt;Dialog&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;componentRef&lt;/code&gt;: This is to hold the current reference to the &lt;strong&gt;Dialog Content&lt;/strong&gt; so that we can destroy it in &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy&lt;/code&gt; hook.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s fill the fields out&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;86700905122548350000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;; // &lt;-- import AnimationState

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;p&gt;
      dynamic-dialog-root works!
    &lt;/p&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    animationState: AnimationState = AnimationState.Enter;
    // Make sure you import AnimationEvent from @angular/animations
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

  constructor() {
  }

  ngAfterViewInit(): void {
  }

  ngOnDestroy(): void {
  }
}`, `86700905122548350000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- import AnimationState&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;p&gt;
      dynamic-dialog-root works!
    &amp;lt;/p&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Make sure you import AnimationEvent from @angular/animations&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We are also going to have a couple of things injected to &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; using &lt;strong&gt;Dependency Injection (DI)&lt;/strong&gt; &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;: Our custom-made &lt;code class=&quot;language-text&quot;&gt;configuration&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;: Our custom-made &lt;code class=&quot;language-text&quot;&gt;dialogRef&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ComponentFactoryResolver&lt;/code&gt;: When you define and use a regular &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; in &lt;strong&gt;Angular&lt;/strong&gt;, &lt;strong&gt;Angular&lt;/strong&gt; will take the metadata from &lt;code class=&quot;language-text&quot;&gt;@Component()&lt;/code&gt; decorator and create a &lt;code class=&quot;language-text&quot;&gt;factory&lt;/code&gt; out of those metadata for your &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt;. Our &lt;strong&gt;Dialog&lt;/strong&gt; will be rendered dynamically on the screen. Hence, we are going to need &lt;code class=&quot;language-text&quot;&gt;ComponentFactoryResolver&lt;/code&gt; to create the &lt;code class=&quot;language-text&quot;&gt;factory&lt;/code&gt; ourselves. &lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ChangeDetectorRef&lt;/code&gt;: The idea is we will start constructing our &lt;strong&gt;Dialog Content Component&lt;/strong&gt; in &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit&lt;/code&gt; hook after the initial &lt;strong&gt;DOM&lt;/strong&gt; has been loaded. And we are also leveraging &lt;code class=&quot;language-text&quot;&gt;OnPush&lt;/code&gt; strategy so after we create our &lt;strong&gt;Dialog Content Component&lt;/strong&gt;, we want to call &lt;code class=&quot;language-text&quot;&gt;changeDetectorRef.markForCheck()&lt;/code&gt; so &lt;strong&gt;Angular Change Detection Mechanism&lt;/strong&gt; will check this &lt;strong&gt;Dialog Root Component&lt;/strong&gt; for update and we only do it once. The later change detection should be happening inside of the &lt;strong&gt;Dialog Content Component&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Again, let’s fill these out&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;41018215897581500000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;p&gt;
      dynamic-dialog-root works!
    &lt;/p&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

  constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
  }

  ngAfterViewInit(): void {
  }

  ngOnDestroy(): void {
  }
}`, `41018215897581500000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;p&gt;
      dynamic-dialog-root works!
    &amp;lt;/p&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s fill out the &lt;code class=&quot;language-text&quot;&gt;template&lt;/code&gt; next&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;86401238311179850000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    // Grab the Directive to use in the TypeScript portion
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
    }

    ngOnDestroy(): void {
    }
}`, `86401238311179850000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Grab the Directive to use in the TypeScript portion&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I grab the &lt;code class=&quot;language-text&quot;&gt;HTML&lt;/code&gt; directly from &lt;a href=&quot;https://bulma.io/documentation/components/modal/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Bulma Modal&lt;/a&gt; and change the &lt;code class=&quot;language-text&quot;&gt;title&lt;/code&gt; to use &lt;code class=&quot;language-text&quot;&gt;dialogConfig.header&lt;/code&gt;. I also replace everything in between &lt;code class=&quot;language-text&quot;&gt;&amp;lt;section class=&amp;quot;modal-card-body&amp;quot;&amp;gt;&amp;lt;/section&amp;gt;&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ng-template&amp;gt;&amp;lt;/ng-template&amp;gt;&lt;/code&gt; and use our &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; on the &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt;. If you know how &lt;strong&gt;Dynamic Component&lt;/strong&gt; works in &lt;strong&gt;Angular,&lt;/strong&gt; you’ll kind of see what is going on here already. We use &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt;, bind &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; and if you recall, we inject &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; in our &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;. This all essentially means we’re grabbing the &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt; as our &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; and we can use that as the &lt;strong&gt;Insertion Point&lt;/strong&gt; for our &lt;strong&gt;Dialog Content Component&lt;/strong&gt;. &lt;/p&gt;
&lt;p&gt;Now, let’s fill out &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy()&lt;/code&gt; shall we&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;50405907435457450000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }
}`, `50405907435457450000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As mention before, in &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit()&lt;/code&gt;, we will &lt;code class=&quot;language-text&quot;&gt;loadContentComponent()&lt;/code&gt; using &lt;code class=&quot;language-text&quot;&gt;ComponentFactoryResolver&lt;/code&gt; and then mark the &lt;strong&gt;Dialog Root&lt;/strong&gt; for &lt;strong&gt;Change Detection Check&lt;/strong&gt; with &lt;code class=&quot;language-text&quot;&gt;ChangeDetectorRef.markForCheck()&lt;/code&gt;. In &lt;code class=&quot;language-text&quot;&gt;loadContentComponent()&lt;/code&gt;, we also grab the &lt;code class=&quot;language-text&quot;&gt;viewContainerRef&lt;/code&gt; from our &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; to act as the &lt;strong&gt;Insertion Point&lt;/strong&gt; for our &lt;strong&gt;Dialog Content Component.&lt;/strong&gt; If you notice, you will see that we haven’t set our &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; anywhere in this &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; and you are absolutely right. We will assign &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; at an earlier point, in a different place. In &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy()&lt;/code&gt;, we just do some cleaning up with &lt;code class=&quot;language-text&quot;&gt;componentRef&lt;/code&gt;. Pretty self-explanatory 😊. Let’s add one more method to &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; before moving on&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;50856043652812644000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    // Add this method
    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }
}`, `50856043652812644000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Add this method&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Remember I said we are going to use &lt;code class=&quot;language-text&quot;&gt;animationState&lt;/code&gt; to make meaningful decision about closing the &lt;strong&gt;Dialog?&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;startExitAnimation()&lt;/code&gt; will allow us to start that decision making process. There is still more work to be done in &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;, but we will need to come back to it later. Next stop will be our &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; &lt;/p&gt;
&lt;h3 id=&quot;dynamicdialogref&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dynamicdialogref&quot; aria-label=&quot;dynamicdialogref permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;DynamicDialogRef&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; is the reference to the current instance &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; that is being opened (and managed by &lt;strong&gt;Angular CDK&lt;/strong&gt;). We will need a couple of fields and methods in &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt;: This will be a &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; that will emit when the &lt;strong&gt;Dialog&lt;/strong&gt; is &lt;strong&gt;about&lt;/strong&gt; to close. We will keep the &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; private and expose the &lt;code class=&quot;language-text&quot;&gt;Observable&lt;/code&gt; counterpart via a &lt;code class=&quot;language-text&quot;&gt;getter&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt;: Same concept as &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt; but this is for when the &lt;strong&gt;Dialog&lt;/strong&gt; has already been closed. We will also pass some optional &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; back to the consumers with &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt; as well.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt;: The instance of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; which is being used by the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; to render the &lt;strong&gt;Dialog&lt;/strong&gt;. We will hook onto the &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; so we can determine when &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt; should emit.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;close(data?: TReturnType): void&lt;/code&gt;: We are going to make the &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; available in &lt;strong&gt;Dependency Injection Context&lt;/strong&gt; so that the &lt;strong&gt;Dialog Content Component&lt;/strong&gt; can have access to the current &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; and will be able to call &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; and pass in some &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; . Eg: when you close a &lt;strong&gt;Confirmation Dialog&lt;/strong&gt; and upon close, you will want to pass &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;false&lt;/code&gt; back to the &lt;strong&gt;Dialog Invoker&lt;/strong&gt; so you can make a decision whether the user confirms the action or not. Again, &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; has a &lt;strong&gt;Generic Type&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;TReturnType&lt;/code&gt; that we can pass in upon injecting &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; in a &lt;strong&gt;Dialog Content Component&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Beside these 4 things, we also need to inject &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; so we can do some clean-up for the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; itself. Now, let’s fill this bad boy up&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;72287539084506240000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { Observable, Subject } from &apos;rxjs&apos;;
import { filter, take } from &apos;rxjs/operators&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;

// A local constant.
const AnimationPhase = {
  START: &apos;start&apos;,
  DONE: &apos;done&apos;
};

export class DynamicDialogRef&lt;TReturnType = any&gt; {
  private beforeClosed\$: Subject&lt;void&gt; = new Subject&lt;void&gt;();
  private afterClosed\$: Subject&lt;TReturnType&gt; = new Subject&lt;TReturnType&gt;();

  componentInstance: DynamicDialogRootComponent;

  constructor(private readonly overlayRef: OverlayRef) {
        overlayRef.backdropClick().pipe(take(1)).subscribe(this.close.bind(this));
  }

  get beforeClosed(): Observable&lt;void&gt; {
    return this.beforeClosed\$.asObservable();
  }

  get afterClosed(): Observable&lt;TReturnType&gt; {
    return this.afterClosed\$.asObservable();
  }

  close(data?: TReturnType): void {
    this.componentInstance.animationStateChanged.pipe(
      filter(event =&gt; event.phaseName === AnimationPhase.START),
      take(1)
    ).subscribe(() =&gt; {
      this.beforeClosed\$.next();
      this.beforeClosed\$.complete();
      this.overlayRef.detachBackdrop();
    });

    this.componentInstance.animationStateChanged.pipe(
      filter(event =&gt; event.phaseName === AnimationPhase.DONE &amp;&amp; event.toState === AnimationState.Leave),
      take(1)
    ).subscribe(() =&gt; {
      this.overlayRef.dispose();
      this.afterClosed\$.next(data);
      this.afterClosed\$.complete();
      this.componentInstance = null;
    });

    this.componentInstance.startExitAnimation();
  }
}`, `72287539084506240000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Observable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Subject &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rxjs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; filter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; take &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rxjs/operators&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// A local constant.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; AnimationPhase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;START&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;start&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;DONE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; beforeClosed$&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Subject&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; afterClosed$&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Subject&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  componentInstance&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlayRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;backdropClick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;beforeClosed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;beforeClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;asObservable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;afterClosed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;asObservable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; TReturnType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationStateChanged&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phaseName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; AnimationPhase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;START&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;beforeClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;beforeClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;detachBackdrop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationStateChanged&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phaseName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; AnimationPhase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DONE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;toState &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dispose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quite a lot is happening here. Let’s go through it&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AnimationPhase&lt;/code&gt; is just a local constant that has &lt;code class=&quot;language-text&quot;&gt;START&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;DONE&lt;/code&gt; properties on it. You can extract this out to its own file or some other place where you keep track of all of your constants. To me, this would work fine. &lt;/li&gt;
&lt;li&gt;In the &lt;code class=&quot;language-text&quot;&gt;constructor&lt;/code&gt;, we subscribe to &lt;code class=&quot;language-text&quot;&gt;backdropClick()&lt;/code&gt; on the &lt;code class=&quot;language-text&quot;&gt;overlayRef&lt;/code&gt; and call &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;Declare all of our fields &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt; , &lt;code class=&quot;language-text&quot;&gt;beforeClosed&lt;/code&gt; getter, &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;afterClosed&lt;/code&gt; getter, &lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt;, injected &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; method.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;beforeClosed&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;afterClosed&lt;/code&gt; getters will allow us to provide the underline &lt;code class=&quot;language-text&quot;&gt;Observable&lt;/code&gt; from their &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; without exposing the &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; has the ability to emit new values and we do not want the consumers to be able to do that. &lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;close(data?: TReturnType)&lt;/code&gt;: The meat of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;. We setup two &lt;code class=&quot;language-text&quot;&gt;Subscription&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt;: one is for when &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.START&lt;/code&gt; and another is for when &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.DONE&lt;/code&gt;. When we first invoke &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt;, the animations will actually start first and &lt;code class=&quot;language-text&quot;&gt;@angular/animations&lt;/code&gt; allows us to hook into these &lt;code class=&quot;language-text&quot;&gt;AnimationEvent&lt;/code&gt; . So during &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.START&lt;/code&gt;, we will have the &lt;code class=&quot;language-text&quot;&gt;Subscription&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt; by the &lt;code class=&quot;language-text&quot;&gt;phaseName&lt;/code&gt;, and we are only interested in &lt;strong&gt;ONE&lt;/strong&gt; and &lt;strong&gt;ONLY ONE&lt;/strong&gt; emitted value so we &lt;code class=&quot;language-text&quot;&gt;take(1)&lt;/code&gt;. Then, we have &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt; emit and complete right away so it cleans itself up. Finally, we will have the &lt;code class=&quot;language-text&quot;&gt;overlayRef&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;detachBackdrop()&lt;/code&gt;. The other &lt;code class=&quot;language-text&quot;&gt;Subscription&lt;/code&gt; works in a similar manner. &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt; by &lt;code class=&quot;language-text&quot;&gt;phaseName&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;take(1)&lt;/code&gt; and have &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt; emit new value with &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; then complete itself. We also call &lt;code class=&quot;language-text&quot;&gt;overlayRef.dispose()&lt;/code&gt; to finally dispose the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; and nullify &lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt;. After setting up the &lt;code class=&quot;language-text&quot;&gt;Subscriptions&lt;/code&gt;, we actually invoke &lt;code class=&quot;language-text&quot;&gt;startExitAnimation()&lt;/code&gt; so the &lt;code class=&quot;language-text&quot;&gt;Subscriptions&lt;/code&gt; are &lt;strong&gt;ready&lt;/strong&gt; when the animation starts.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That’s it for &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;. Now, let’s go back to &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; since we have &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef.close()&lt;/code&gt; ready.&lt;/p&gt;
&lt;h3 id=&quot;finish-up-dynamicdialogrootcomponent&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#finish-up-dynamicdialogrootcomponent&quot; aria-label=&quot;finish up dynamicdialogrootcomponent permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Finish up DynamicDialogRootComponent&lt;/h3&gt;
&lt;p&gt;Let’s first setup some methods that will invoke &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef.close()&lt;/code&gt; by default. &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;86480592390777210000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild,
    HostListener
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }

    closeDialog() {
        this.dialogRef.close();
    }

    @HostListener(&amp;quot;document:keydown&amp;quot;, [&amp;quot;\$event.key&amp;quot;])
    private handleEscapeKey(key: string) {
        if (key === &apos;Escape&apos;) {
          this.closeDialog();
        }
    }
}`, `86480592390777210000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    HostListener
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;document:keydown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$event.key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEscapeKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Escape&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We added 2 methods&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;closeDialog()&lt;/code&gt;: Handle closing the &lt;strong&gt;Dialog&lt;/strong&gt; upon clicking the &lt;strong&gt;Close Icon&lt;/strong&gt; on the header or clicking on the backdrop.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;handleEscapeKey()&lt;/code&gt;: A &lt;code class=&quot;language-text&quot;&gt;HostListener&lt;/code&gt; that listens to &lt;code class=&quot;language-text&quot;&gt;document:keydown&lt;/code&gt; event and will check if it’s the &lt;code class=&quot;language-text&quot;&gt;Escape&lt;/code&gt; key to close the &lt;strong&gt;Dialog&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, we are going to add &lt;code class=&quot;language-text&quot;&gt;animations&lt;/code&gt; to this &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m going to utilize an npm package called &lt;code class=&quot;language-text&quot;&gt;ng-animate&lt;/code&gt; to help with my animation skills. If you want to follow along, please run &lt;code class=&quot;language-text&quot;&gt;npm i ng-animate&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;90300622360747210000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { animateChild, AnimationEvent, group, query, transition, trigger, useAnimation } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild,
    HostListener
} from &apos;@angular/core&apos;;
import { fadeIn, fadeOut, zoomIn, zoomOut } from &apos;ng-animate&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [
    trigger(&apos;zoom&apos;, [
      transition(
        &apos;* =&gt; in&apos;,
        useAnimation(zoomIn, { params: { timing: &apos;{{timing}}&apos; } })
      ),
      transition(
        &apos;* =&gt; out&apos;,
        useAnimation(zoomOut, { params: { timing: &apos;{{timing}}&apos; } })
      )
    ]),
    trigger(&apos;animation&apos;, [
      transition(
        \`* =&gt; \${ AnimationState.Enter }\`,
        group([
          useAnimation(fadeIn, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      ),
      transition(
        \`* =&gt; \${ AnimationState.Leave }\`,
        group([
          useAnimation(fadeOut, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      )
    ])
  ]
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }

    closeDialog() {
        this.dialogRef.close();
    }

    @HostListener(&amp;quot;document:keydown&amp;quot;, [&amp;quot;\$event.key&amp;quot;])
    private handleEscapeKey(key: string) {
        if (key === &apos;Escape&apos;) {
          this.closeDialog();
        }
    }
}`, `90300622360747210000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; animateChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AnimationEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; group&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; transition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; trigger&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useAnimation &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    HostListener
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomOut &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ng-animate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; in&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; out&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;animation&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;document:keydown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$event.key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEscapeKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Escape&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, this is going to be painful. I would suggest reading more about &lt;a href=&quot;https://angular.io/guide/animations&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular Animations&lt;/a&gt;. Basically, we setup two &lt;code class=&quot;language-text&quot;&gt;triggers&lt;/code&gt; : &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; will be responsible for animating the &lt;strong&gt;Dialog Content&lt;/strong&gt; while &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; will be responsible for animating the &lt;strong&gt;Dialog Container&lt;/strong&gt;. In &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; trigger, we setup &lt;code class=&quot;language-text&quot;&gt;fadeIn&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;fadeOut&lt;/code&gt; animation (from &lt;code class=&quot;language-text&quot;&gt;ng-animate&lt;/code&gt;, if you’re comfortable with &lt;strong&gt;Animations&lt;/strong&gt; in general, feel free to setup your own animations) based on the &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt; , we also leverage &lt;code class=&quot;language-text&quot;&gt;Animation Params&lt;/code&gt; (eg: &lt;code class=&quot;language-text&quot;&gt;{{timing}}&lt;/code&gt;) to pass in configurable &lt;code class=&quot;language-text&quot;&gt;Animation Configuration&lt;/code&gt; to our animations. Remember &lt;code class=&quot;language-text&quot;&gt;containerAnimationTiming&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;contentAnimationTiming&lt;/code&gt; and such? Those will come into play here. Last but not least, we also setup &lt;code class=&quot;language-text&quot;&gt;query&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; trigger inside of &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; trigger so we are able to run &lt;code class=&quot;language-text&quot;&gt;animateChild&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;delay&lt;/code&gt;, again, remember &lt;code class=&quot;language-text&quot;&gt;animateChildDelay&lt;/code&gt; 😅?! Again, I would encourage reading more about &lt;strong&gt;Angular Animations&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Finally, let’s finish up the &lt;code class=&quot;language-text&quot;&gt;template&lt;/code&gt; and hook everything together&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;31452410293332455000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { animateChild, AnimationEvent, group, query, transition, trigger, useAnimation } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild,
    HostListener
} from &apos;@angular/core&apos;;
import { fadeIn, fadeOut, zoomIn, zoomOut } from &apos;ng-animate&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
      [@animation]=&amp;quot;{
        value: animationState,
        params: {
          timing: dialogConfig.containerAnimationTiming,
          delayChild: dialogConfig.animationChildDelay
        }
      }&amp;quot;
      (@animation.start)=&amp;quot;animationStateChanged.emit(\$event)&amp;quot;
      (@animation.done)=&amp;quot;animationStateChanged.emit(\$event)&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot; (click)=&amp;quot;closeDialog()&amp;quot;&gt;&lt;/div&gt;
      &lt;div
        class=&amp;quot;modal-card&amp;quot;
        [@zoom]=&amp;quot;{
          value: animationState == &apos;enter&apos; ? &apos;in&apos; : &apos;out&apos;,
          params: { timing: dialogConfig.contentAnimationTiming }
        }&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
            (click)=&amp;quot;closeDialog()&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
\`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [
    trigger(&apos;zoom&apos;, [
      transition(
        &apos;* =&gt; in&apos;,
        useAnimation(zoomIn, { params: { timing: &apos;{{timing}}&apos; } })
      ),
      transition(
        &apos;* =&gt; out&apos;,
        useAnimation(zoomOut, { params: { timing: &apos;{{timing}}&apos; } })
      )
    ]),
    trigger(&apos;animation&apos;, [
      transition(
        \`* =&gt; \${ AnimationState.Enter }\`,
        group([
          useAnimation(fadeIn, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      ),
      transition(
        \`* =&gt; \${ AnimationState.Leave }\`,
        group([
          useAnimation(fadeOut, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      )
    ])
  ]
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }

    closeDialog() {
        this.dialogRef.close();
    }

    @HostListener(&amp;quot;document:keydown&amp;quot;, [&amp;quot;\$event.key&amp;quot;])
    private handleEscapeKey(key: string) {
        if (key === &apos;Escape&apos;) {
          this.closeDialog();
        }
    }
}`, `31452410293332455000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; animateChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AnimationEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; group&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; transition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; trigger&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useAnimation &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    HostListener
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomOut &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ng-animate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
      [@animation]=&quot;{
        value: animationState,
        params: {
          timing: dialogConfig.containerAnimationTiming,
          delayChild: dialogConfig.animationChildDelay
        }
      }&quot;
      (@animation.start)=&quot;animationStateChanged.emit($event)&quot;
      (@animation.done)=&quot;animationStateChanged.emit($event)&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot; (click)=&quot;closeDialog()&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div
        class=&quot;modal-card&quot;
        [@zoom]=&quot;{
          value: animationState == &apos;enter&apos; ? &apos;in&apos; : &apos;out&apos;,
          params: { timing: dialogConfig.contentAnimationTiming }
        }&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
            (click)=&quot;closeDialog()&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; in&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; out&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;animation&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;document:keydown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$event.key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEscapeKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Escape&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We hook up &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; trigger to the top &lt;strong&gt;DOM&lt;/strong&gt; element which is the &lt;code class=&quot;language-text&quot;&gt;modal&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; trigger to &lt;code class=&quot;language-text&quot;&gt;modal-card&lt;/code&gt;. We also use &lt;code class=&quot;language-text&quot;&gt;dialogConfig&lt;/code&gt; to pass in the configurable &lt;strong&gt;Animation Params&lt;/strong&gt;. Next, we set &lt;code class=&quot;language-text&quot;&gt;@animation.start&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;@animation.done&lt;/code&gt; event then have &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt; emit accordingly. You see how &lt;code class=&quot;language-text&quot;&gt;startExitAnimation&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef.close()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt; all play together now? Finally, we hook up &lt;code class=&quot;language-text&quot;&gt;closeDialog()&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;modal-background&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;button.delete&lt;/code&gt; (&lt;code class=&quot;language-text&quot;&gt;close icon&lt;/code&gt;) on the &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Woohoo 🔥, we are 60% done now 😅. Let’s finish up the last 40% with &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt;&lt;/p&gt;
&lt;h3 id=&quot;dynamicdialogservice&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dynamicdialogservice&quot; aria-label=&quot;dynamicdialogservice permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;DynamicDialogService&lt;/h3&gt;
&lt;p&gt;Beside &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; is the last piece that will allow the consumers to interact with our whole &lt;strong&gt;Dynamic Dialog.&lt;/strong&gt; So open up &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog.service.ts&lt;/code&gt; and jump right in. &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; only exposes one method which is &lt;code class=&quot;language-text&quot;&gt;open&amp;lt;TReturnType = any&amp;gt;()&lt;/code&gt; so the consumers can use this method to &lt;strong&gt;open&lt;/strong&gt; the &lt;strong&gt;Dialog&lt;/strong&gt;. &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;63671538485287240000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
  }
}`, `63671538485287240000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s import and inject everything we need first. After that, we declare a &lt;code class=&quot;language-text&quot;&gt;private readonly defaultDialogConfig&lt;/code&gt; which will hold our default configuration of the &lt;strong&gt;Dialog&lt;/strong&gt;. We did setup some default configurations inside of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; upon instantiation. Here in the &lt;code class=&quot;language-text&quot;&gt;constructor&lt;/code&gt;, we are going to be &lt;strong&gt;defaulting&lt;/strong&gt; some &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; as well&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;disposeOnNavigation&lt;/code&gt;: Self-explanatory. We want to close the dialog if we navigate away from the current page so we clean up and prevent potential memory-leak.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;hasBackdrop&lt;/code&gt;: This can be set default or not. I set it to &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt;. If it’s &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt;, then &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; will also render a &lt;code class=&quot;language-text&quot;&gt;cdk-backdrop&lt;/code&gt; element along side the &lt;code class=&quot;language-text&quot;&gt;cdk-overlay&lt;/code&gt; on our &lt;strong&gt;DOM Tree&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;panelClass&lt;/code&gt;: Customizable &lt;code class=&quot;language-text&quot;&gt;HTML&lt;/code&gt; class so we can customize the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; element should we desire.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;scrollStrategy&lt;/code&gt;: Self-explanatory. Set the scrolling behavior when the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; is opened. We default it to &lt;code class=&quot;language-text&quot;&gt;BlockScrollStrategy&lt;/code&gt; here. Read more about &lt;a href=&quot;https://material.angular.io/cdk/overlay/overview#scroll-strategies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;ScrollStrategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;positionStrategy&lt;/code&gt;: Set the position of the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; when it’s opened. Default to &lt;code class=&quot;language-text&quot;&gt;center&lt;/code&gt;. Read more about &lt;a href=&quot;https://material.angular.io/cdk/overlay/overview#position-strategies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;PositionStrategies&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, we declare &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; method. &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; takes in an optional &lt;strong&gt;Generic Type&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;TReturnType&lt;/code&gt; . We will have the &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; method to return an &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&amp;lt;TReturnType&amp;gt;&lt;/code&gt; so the &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef.afterClosed&lt;/code&gt; will have the correct type when the consumers subscribe to it. &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; will expect a &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; for the &lt;strong&gt;Dialog Content&lt;/strong&gt; (remember &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt;, here’s the &lt;strong&gt;earlier point&lt;/strong&gt; that we set the &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt;) and a &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; to be merged with &lt;code class=&quot;language-text&quot;&gt;defaultDialogConfig&lt;/code&gt;. Afterward, we create our &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt;. Let’s implement &lt;code class=&quot;language-text&quot;&gt;createOverlay()&lt;/code&gt; now. &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;74244650146532740000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
  }

  private createOverlay(config: DynamicDialogConfig): OverlayRef {
    return this.overlay.create(config.overlayConfig);
  }
}`, `74244650146532740000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Very simple. We call &lt;code class=&quot;language-text&quot;&gt;overlay.create()&lt;/code&gt; and pass in the &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; from &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig.overlayConfig&lt;/code&gt;. Now that we have &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt;, we can start creating our custom &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;15579550556286081000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
    const dialogRef = new DynamicDialogRef&lt;TReturnType&gt;(overlayRef);
    dialogRef.componentInstance = this.attachDialogContainer(overlayRef, component, dialogRef, mergeConfig);
  }

  private createOverlay(config: DynamicDialogConfig): OverlayRef {
    return this.overlay.create(config.overlayConfig);
  }
}`, `15579550556286081000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dialogRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attachDialogContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Remember &lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; that has the type of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; will still be created dynamically and this is really where &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; from &lt;strong&gt;Angular CDK&lt;/strong&gt; come into play. &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;PortalOutlet&lt;/code&gt; which can &lt;code class=&quot;language-text&quot;&gt;attach&lt;/code&gt; a &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt; to render that &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; dynamically on the screen. Normally, you can leverage &lt;a href=&quot;https://angular.io/guide/dynamic-component-loader&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Dynamic Component Loader&lt;/a&gt; to create the &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; dynamically. However, &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; from &lt;strong&gt;Angular&lt;/strong&gt; &lt;strong&gt;CDK&lt;/strong&gt; provide better APIs to work with, and to clean up. With that in mind, let’s work on &lt;code class=&quot;language-text&quot;&gt;attachDialogContainer&lt;/code&gt; method&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;55871788035541090000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
    const dialogRef = new DynamicDialogRef&lt;TReturnType&gt;(overlayRef);
    dialogRef.componentInstance = this.attachDialogContainer(overlayRef, component, dialogRef, mergeConfig);
    return dialogRef;
  }

  private createOverlay(config: DynamicDialogConfig): OverlayRef {
    return this.overlay.create(config.overlayConfig);
  }

  private attachDialogContainer(overlayRef: OverlayRef, component: Type&lt;any&gt;, dialogRef: DynamicDialogRef, dialogConfig: DynamicDialogConfig): DynamicDialogRootComponent {
    const injector = this.createInjector(dialogRef, dialogConfig);
    const portal = new ComponentPortal(DynamicDialogRootComponent, null, injector);
    const ref = overlayRef.attach(portal);
    ref.instance.contentComponentType = component;
    return ref.instance;
  }

  private createInjector(ref: DynamicDialogRef, config: DynamicDialogConfig): PortalInjector {
    const injectorTokenMap = new WeakMap();
    injectorTokenMap.set(DynamicDialogRef, ref);
    injectorTokenMap.set(DynamicDialogConfig, config);
    return new PortalInjector(this.injector, injectorTokenMap);
  }
}`, `55871788035541090000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dialogRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attachDialogContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dialogRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;attachDialogContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; injector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; portal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComponentPortal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; injector&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ref &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;portal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ref&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; injectorTokenMap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WeakMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    injectorTokenMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ref&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    injectorTokenMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PortalInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; injectorTokenMap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First thing is we want to &lt;code class=&quot;language-text&quot;&gt;createInjector()&lt;/code&gt; for the &lt;strong&gt;Dialog&lt;/strong&gt; because we want &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; to be available via &lt;strong&gt;Dependency&lt;/strong&gt; &lt;strong&gt;Injection&lt;/strong&gt; in the &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; instance which ultimately manages &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; and custom &lt;strong&gt;Dialog&lt;/strong&gt; &lt;strong&gt;Content&lt;/strong&gt; &lt;strong&gt;Component&lt;/strong&gt; which will also have access to the same &lt;strong&gt;Injector&lt;/strong&gt; which provides the same &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; instances used when the &lt;strong&gt;Dialog&lt;/strong&gt; is opened with &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; will just merge a token map (&lt;code class=&quot;language-text&quot;&gt;WeakMap&lt;/code&gt; here) with the &lt;code class=&quot;language-text&quot;&gt;parentInjector&lt;/code&gt; so it can provide our custom tokens to the &lt;strong&gt;Injector.&lt;/strong&gt; With the &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; ready, we can then create an instance of &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt; with the &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; and our own &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;. All that’s left to do is to attach this &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt; to the &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt;. Call &lt;code class=&quot;language-text&quot;&gt;overlayRef.attach()&lt;/code&gt; to do so. Returned value is the reference to the underline &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; used to instantiate &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt;, which in this case is our &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; and this is where we will assign the passed-in &lt;code class=&quot;language-text&quot;&gt;component&lt;/code&gt; that &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; field. Finally, we return the &lt;code class=&quot;language-text&quot;&gt;ref.instance&lt;/code&gt; which is the instance of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; which is being managed by the current &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt;. Ultimately, we return the &lt;code class=&quot;language-text&quot;&gt;dialogRef&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; so the consumers have a hold of the &lt;code class=&quot;language-text&quot;&gt;dialogRef&lt;/code&gt; so they can subscribe to its events when it’s closed. &lt;/p&gt;
&lt;h3 id=&quot;dynamicdialogmodule&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dynamicdialogmodule&quot; aria-label=&quot;dynamicdialogmodule permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;DynamicDialogModule&lt;/h3&gt;
&lt;p&gt;Every pieces of the &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; has been completed. However, we need to put everything in &lt;code class=&quot;language-text&quot;&gt;DynamicDialogModule&lt;/code&gt; before we can use it. Open &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog.module.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;32788442005607000000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { OverlayModule } from &apos;@angular/cdk/overlay&apos;;
import { CommonModule } from &apos;@angular/common&apos;;
import { NgModule } from &apos;@angular/core&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogService } from &apos;./dynamic-dialog.service&apos;;


@NgModule({
  declarations: [DynamicDialogContentDirective, DynamicDialogRootComponent],
  imports: [CommonModule, OverlayModule], // &lt;-- import OverlayModule
  entryComponents: [DynamicDialogRootComponent], // &lt;-- add DynamicDialogRootComponent to entryComponents. Make sure to put it under declarations as well if you haven&apos;t already
  providers: [DynamicDialogService] // provide DynamicDialogService
})
export class DynamicDialogModule {
}`, `32788442005607000000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; OverlayModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; CommonModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;


@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;CommonModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- import OverlayModule&lt;/span&gt;
  entryComponents&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- add DynamicDialogRootComponent to entryComponents. Make sure to put it under declarations as well if you haven&apos;t already&lt;/span&gt;
  providers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DynamicDialogService&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// provide DynamicDialogService&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;simple-usage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#simple-usage&quot; aria-label=&quot;simple usage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Simple Usage&lt;/h3&gt;
&lt;p&gt;Before we use our &lt;strong&gt;Dialog&lt;/strong&gt;, let’s create a simple &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; to be our &lt;strong&gt;Dialog Content&lt;/strong&gt;. Run the following command&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;13902967033643977000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`# assume you are at the root level of the project (cdk-bulma-dialog)
ng generate component test-dialog 
--skipTests 
--inlineTemplate 
--inlineStyle 
--changeDetection=OnPush
--entryComponent`, `13902967033643977000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;# assume you are at the root level of the project (cdk-bulma-dialog)
ng generate component test-dialog 
--skipTests 
--inlineTemplate 
--inlineStyle 
--changeDetection=OnPush
--entryComponent&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We use the &lt;strong&gt;CLI&lt;/strong&gt; to generate a &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;inlineTemplate&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;inlineStyle&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;skipTests&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;changeDetection=OnPush&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;entryComponent&lt;/code&gt; flags. This component will be really simple so we will have everything &lt;code class=&quot;language-text&quot;&gt;inline&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;entryComponent&lt;/code&gt; flag will put this component in &lt;code class=&quot;language-text&quot;&gt;entryComponents&lt;/code&gt; array automatically for us. Now, let’s open &lt;code class=&quot;language-text&quot;&gt;test-dialog.component.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;50232777965401310000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { ChangeDetectionStrategy, Component, OnInit } from &apos;@angular/core&apos;;

@Component({
  selector: &apos;app-test-dialog&apos;,
    template: \`
        &lt;p&gt;test-dialog works!&lt;/p&gt;
        &lt;button class=&amp;quot;button&amp;quot; (click)=&amp;quot;close()&amp;quot;&gt;Close&lt;/button&gt;
    \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class TestDialogComponent implements OnInit {

  constructor(
        private readonly dialogConfig: DynamicDialogConfig, 
        private readonly dialogRef: DynamicDialogRef&lt;string&gt;
    ) {}

  ngOnInit() {
  }

  close() {
    this.dialogRef.close(&apos;closed from inside content dialog&apos;);
  }
}`, `50232777965401310000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnInit &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-test-dialog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
        &amp;lt;p&gt;test-dialog works!&amp;lt;/p&gt;
        &amp;lt;button class=&quot;button&quot; (click)=&quot;close()&quot;&gt;Close&amp;lt;/button&gt;
    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TestDialogComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OnInit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;closed from inside content dialog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We only add a &lt;code class=&quot;language-text&quot;&gt;button&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;(click)&lt;/code&gt; bound to &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; method. We also inject &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&amp;lt;string&amp;gt;&lt;/code&gt; to check if our &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; works or not. In &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt;, we call &lt;code class=&quot;language-text&quot;&gt;dialogRef.close()&lt;/code&gt; and pass in a string &lt;code class=&quot;language-text&quot;&gt;&amp;#39;closed from inside content dialog&amp;#39;&lt;/code&gt;. Now, open &lt;code class=&quot;language-text&quot;&gt;app.component.html&lt;/code&gt; &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;32309509093860102000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;button class=&amp;quot;button&amp;quot; (click)=&amp;quot;showOverlay()&amp;quot;&gt;Show Overlay&lt;/button&gt;`, `32309509093860102000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;(click)&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;showOverlay()&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Show Overlay&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;then open &lt;code class=&quot;language-text&quot;&gt;app.component.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;87797034674663780000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Component } from &apos;@angular/core&apos;;
import { DynamicDialogService } from &apos;./dynamic-dialog/dynamic-dialog.service&apos;;
import { DynamicDialogConfig } from &apos;./dynamic-dialog/models/dynamic-dialog-config.model&apos;;
import { TestDialogComponent } from &apos;./test-dialog/test-dialog.component&apos;;

@Component({
  selector: &apos;app-root&apos;,
  templateUrl: &apos;./app.component.html&apos;,
  styleUrls: [&apos;./app.component.scss&apos;]
})
export class AppComponent {
  constructor(private readonly dynamicDialogService: DynamicDialogService) {
  }

  showOverlay() {
    const config = new DynamicDialogConfig();
    config.header = TestDialogComponent.name;
    const ref = this.dynamicDialogService.open&lt;string&gt;(TestDialogComponent, config);
    ref.afterClosed.subscribe(data =&gt; {
      console.log(&apos;closed with data&apos;, data);
    });
  }
}`, `87797034674663780000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Component &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog/dynamic-dialog.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog/models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; TestDialogComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./test-dialog/test-dialog.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  templateUrl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  styleUrls&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./app.component.scss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dynamicDialogService&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;showOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;header &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ref &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dynamicDialogService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;closed with data&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We inject &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; and implement &lt;code class=&quot;language-text&quot;&gt;showOverlay()&lt;/code&gt; method:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Instantiate a new &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;, set the &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt; to the name of &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Call &lt;code class=&quot;language-text&quot;&gt;dynamicDialogService.open()&lt;/code&gt; , with &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;config&lt;/code&gt; as the arguments, then assign the returned &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; back to local variable &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Subscribe to &lt;code class=&quot;language-text&quot;&gt;ref.afterClosed&lt;/code&gt; and log the &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; passed from within &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent.close()&lt;/code&gt; method.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Open &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt; &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;45941875647580340000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { NgModule } from &apos;@angular/core&apos;;
import { BrowserModule } from &apos;@angular/platform-browser&apos;;
import { BrowserAnimationsModule } from &apos;@angular/platform-browser/animations&apos;; // &lt;-- add this import
import { AppComponent } from &apos;./app.component&apos;;
import { DynamicDialogModule } from &apos;./dynamic-dialog/dynamic-dialog.module&apos;;
import { TestDialogComponent } from &apos;./test-dialog/test-dialog.component&apos;;

@NgModule({
  declarations: [AppComponent, TestDialogComponent],
  imports: [BrowserModule, BrowserAnimationsModule, DynamicDialogModule],
  bootstrap: [AppComponent],
  entryComponents: [TestDialogComponent]
})
export class AppModule {
}`, `45941875647580340000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserAnimationsModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- add this import&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AppComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog/dynamic-dialog.module&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; TestDialogComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./test-dialog/test-dialog.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BrowserModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BrowserAnimationsModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DynamicDialogModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bootstrap&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  entryComponents&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Make sure you have &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;entryComponents&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;DynamicDialogModule&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;imports&lt;/code&gt;. Now, everything is ready. Moment of truth! Run your &lt;strong&gt;Angular&lt;/strong&gt; application&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;23786898496509900000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng serve -o`, `23786898496509900000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng serve -o&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You should see the following on the screen&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b83c04dd99f2bc088bb714564a38dc44/fca82/show-overlay-btn.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 92.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsSAAALEgHS3X78AAAAVklEQVQ4y+2UMQrAUAhDvf9VnR1UNKUFW/hb6x86GIiIwzMuEjNDRODuMLOWVRWEjcpM0Fl2OSIeYG2o/k2q0gVch1/OHOAAB/gfYNc3sJNu1daE9Q8PUTvnj4pducIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;show overlay btn&quot;
        title=&quot;show overlay btn&quot;
        src=&quot;/static/b83c04dd99f2bc088bb714564a38dc44/1bed9/show-overlay-btn.png&quot;
        srcset=&quot;/static/b83c04dd99f2bc088bb714564a38dc44/7b64c/show-overlay-btn.png 160w,
/static/b83c04dd99f2bc088bb714564a38dc44/4e610/show-overlay-btn.png 320w,
/static/b83c04dd99f2bc088bb714564a38dc44/1bed9/show-overlay-btn.png 640w,
/static/b83c04dd99f2bc088bb714564a38dc44/7d769/show-overlay-btn.png 960w,
/static/b83c04dd99f2bc088bb714564a38dc44/f3baa/show-overlay-btn.png 1280w,
/static/b83c04dd99f2bc088bb714564a38dc44/fca82/show-overlay-btn.png 2058w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Lonely Show Overlay button&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Clicking on the &lt;code class=&quot;language-text&quot;&gt;Show Overlay&lt;/code&gt; button will bring up our &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; as a &lt;strong&gt;Dialog&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/87966e6ae7e47878673d6d0a91b30b4d/9e121/overlay.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 91.875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsSAAALEgHS3X78AAAA+ElEQVQ4y82TSwqDMBCGPYOKuvCtV3DhDdwJuhJvogjq/cSNB9GNulD+khSp6QNsLaWBj0kC8zF5DGeaJgzDAImWZdG4zT+Bu0q2DXM3PyXcqjsvZYS3I39ReBbu/iFc132L+4KYCjVNgyiKD/A8/xRBEGjO3sFtZlVV4fs+iqJAlmXI85xC1nVdM1RVRWNZlvA8j+batn0TOo4DWZaRJAmmaULf95RhGDCOI16NZVkQRREkSaIORkg20zTFuq6Y5xlHRxzHj0JSrqIoCMMQbduiaRp0XXeIIAhoLnPkfduRNtR1nV72Efa5X/uHL7/N3wh/03p/K7wA7ShWilPFNB4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;overlay&quot;
        title=&quot;overlay&quot;
        src=&quot;/static/87966e6ae7e47878673d6d0a91b30b4d/1bed9/overlay.png&quot;
        srcset=&quot;/static/87966e6ae7e47878673d6d0a91b30b4d/7b64c/overlay.png 160w,
/static/87966e6ae7e47878673d6d0a91b30b4d/4e610/overlay.png 320w,
/static/87966e6ae7e47878673d6d0a91b30b4d/1bed9/overlay.png 640w,
/static/87966e6ae7e47878673d6d0a91b30b4d/7d769/overlay.png 960w,
/static/87966e6ae7e47878673d6d0a91b30b4d/f3baa/overlay.png 1280w,
/static/87966e6ae7e47878673d6d0a91b30b4d/9e121/overlay.png 2062w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Tada!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Open your &lt;strong&gt;Console&lt;/strong&gt;, and click on &lt;code class=&quot;language-text&quot;&gt;Close&lt;/code&gt; button, you’ll see &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;83681296687914610000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`closed with data closed from inside content dialog`, `83681296687914610000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;closed with data closed from inside content dialog&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;logged to the &lt;strong&gt;Console&lt;/strong&gt;. 👍&lt;/p&gt;
&lt;h3 id=&quot;recap&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#recap&quot; aria-label=&quot;recap permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Recap&lt;/h3&gt;
&lt;p&gt;To recap, I have a little ugly diagram&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/27c6a7876f5916d8bb7f7fe73a90d1f0/94b18/diagram.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 91.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsSAAALEgHS3X78AAABZ0lEQVQ4y52U2Y6DMAxF+f/vpA8FCl3YCrQZnUgHBTRdZiy5IbF9fWM7zZZlCc/nM4zjGPq+j6vK/n6/h8fjEfBT53ne7FPN+BmGIdxut6AAgmj7EyDBbdvGQBRmrJz/i2HTNKEoihiYOrO+CnwL2HVduF6vkdkn569rKOjpdAowZr+/5h4Qu7oBNJudxsH6UUtXkkzTtALYSM7SOmd8cEhgVVXR6XK5RHAcWbG7h8D5fF4bqU0ymRsc6rqOYAQQbHZWy4Kd0hyPx5icBI4aOJlzlgrU94IzoCRGAWXvzOqTSRWQw+EQ8jyPY2RzZABLa8aZzFMyK0MaggNX4rqogNQWu03g7DchCT4bQLLxnQogZGYF3Pfu6MgWnNjlFJCmlGUZg3C0gxbdueNbEL+1rTVEvFb69LT5klTrvh/uyNDCG7gXbgDrr54eRv/7GAeGm1mj+P4DOcAy+fiWLa4Di9LxV+/5HeAPLreC+qaycBEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;diagram&quot;
        title=&quot;diagram&quot;
        src=&quot;/static/27c6a7876f5916d8bb7f7fe73a90d1f0/1bed9/diagram.png&quot;
        srcset=&quot;/static/27c6a7876f5916d8bb7f7fe73a90d1f0/7b64c/diagram.png 160w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/4e610/diagram.png 320w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/1bed9/diagram.png 640w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/7d769/diagram.png 960w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/f3baa/diagram.png 1280w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/94b18/diagram.png 1676w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;…😢&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here is the encapsulation of what’s happening under the hood when you call &lt;code class=&quot;language-text&quot;&gt;dynamicDialogService.open()&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; instance is created to manage the current &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; that is being used to handle the current &lt;code class=&quot;language-text&quot;&gt;PortalOutlet&lt;/code&gt; which renders the &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; as its &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt;. Then, we have the &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; to inject the current instances of &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; so we can have access to those in the &lt;strong&gt;Dialog Content Component&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt;). That’s all there is to it. &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; are two very powerful tools that &lt;strong&gt;Angular CDK&lt;/strong&gt; provides with robust APIs which allows developers like us build high quality components like the &lt;strong&gt;DynamicDialog&lt;/strong&gt;. With the same concept, you can apply &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; to build many different common overlay behaviors like: &lt;strong&gt;Tooltip, Drawer, Toast&lt;/strong&gt; etc… 💪&lt;/p&gt;
&lt;p&gt;To conclude, I hope that I was able to share something and you learn something new after this long blog post 🚀. Have fun and good luck. I’ll see you all in the next blog 👋&lt;/p&gt;
&lt;h3 id=&quot;reference&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#reference&quot; aria-label=&quot;reference permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.thoughtram.io/angular/2017/11/20/custom-overlays-with-angulars-cdk.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Custom Overlays With Angular CDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://netbasal.com/creating-powerful-components-with-angular-cdk-2cef53d81cea&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Creating Powerful Components With Angular CDK&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Xây dựng Dynamic Dialog với Angular CDK]]></title><description><![CDATA[Angular CDK là tên viết ngắn gọn cho Angular Component Dev Kit (CDK). Theo như tên gọi, CDK cung cấp cho các bạn một bộ các công cụ dùng để…]]></description><link>https://nartc.netlify.com/blogs/build-dynamic-dialog-angular-cdk/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/build-dynamic-dialog-angular-cdk/</guid><pubDate>Wed, 08 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Angular CDK&lt;/strong&gt; là tên viết ngắn gọn cho &lt;strong&gt;Angular Component Dev Kit (CDK)&lt;/strong&gt;. Theo như tên gọi, CDK cung cấp cho các bạn một bộ các công cụ dùng để build những  &lt;strong&gt;Angular Components&lt;/strong&gt; giàu tính năng và chất lừ mà không cần phải tuân theo tiêu chuẩn của &lt;strong&gt;Material Design&lt;/strong&gt; của &lt;strong&gt;Google&lt;/strong&gt;. Mục đích của CDK là cho phép developers có thể triển khai &lt;em&gt;những patterns và behaviors phổ biến&lt;/em&gt; trong ứng dụng &lt;strong&gt;Angular&lt;/strong&gt; của mình. Có khá nhiều những gói thư viện, patterns, và behaviors khác nhau mà các bạn có thể khám phá bằng việc nghiên cứu &lt;a href=&quot;https://material.angular.io/cdk/categories&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;documentation&lt;/a&gt; của CDK.&lt;/p&gt;
&lt;p&gt;Gần đây, mình đang làm một dự án &lt;strong&gt;Angular&lt;/strong&gt; mà trong dự án này, bọn mình có dùng cùng một lúc các &lt;strong&gt;Bộ UI Component&lt;/strong&gt; như &lt;code class=&quot;language-text&quot;&gt;NgBootstrap&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;PrimeNG&lt;/code&gt;, cũng như một số thư viện lẻ tẻ khác. Mặc dù là việc dùng các thư viện này giúp bọn mình làm xong việc (và nhanh nữa), nhưng việc dùng vô tội vạ đã đẩy dự án đến một vấn đề là có quá nhiều các bộ phận khác nhau mà cần phải maintain, hoặc update. Nói cách khác, &lt;strong&gt;tech debts&lt;/strong&gt; đang bị dồn từng ngày và &lt;strong&gt;sự không thống nhất&lt;/strong&gt; đang ám ảnh toàn bộ dự án. Một ví dụ điển hình nhât là &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; khi mà cần phải hiển thị một &lt;strong&gt;Dialog&lt;/strong&gt; và có thể truyền vào một &lt;strong&gt;Component&lt;/strong&gt; để hiển thị nội dung của &lt;strong&gt;Dialog&lt;/strong&gt; này. Nghe phê phê he? Tại thời điểm mà bọn mình cần tính năng này, &lt;code class=&quot;language-text&quot;&gt;PrimeNG&lt;/code&gt; chưa có hỗ trợ &lt;strong&gt;DynamicDialog&lt;/strong&gt; (bây giờ thì họ có hỗ trợ rồi, nghiên cứu thêm tại &lt;a href=&quot;https://www.primefaces.org/primeng/#/dynamicdialog&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;PrimeNG DynamicDialog&lt;/a&gt;). Một dev trong team mình đã tìm đến &lt;code class=&quot;language-text&quot;&gt;NgBootstrap&lt;/code&gt; vì &lt;strong&gt;NgbModal&lt;/strong&gt; (đọc thêm về &lt;a href=&quot;https://ng-bootstrap.github.io/#/components/modal/examples&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;NgBootstrap NgbModal&lt;/a&gt;). Đó là lý do và cũng là lúc mà dự án có cả &lt;code class=&quot;language-text&quot;&gt;NgBootstrap&lt;/code&gt; lẫn &lt;code class=&quot;language-text&quot;&gt;PrimeNG&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;Nhưng phải có cách nào tốt hơn chứ đúng không? Phải có cái nào mà có thể dùng những cái sẵn có chứ! May mắn cho các bạn là &lt;strong&gt;có&lt;/strong&gt;. &lt;strong&gt;Angular CDK&lt;/strong&gt; có cung cấp một cách khá “dễ” để triển khai &lt;strong&gt;DynamicDialog&lt;/strong&gt; của riêng bạn, có thể kết hợp với &lt;strong&gt;BẤT CỨ&lt;/strong&gt; bộ giao diện mà các bạn đang hoặc muốn sử dụng. Từ đó, mình đã và đang tìm hiểu thêm về &lt;strong&gt;Angular CDK&lt;/strong&gt;, đặc biệt là &lt;strong&gt;Overlay&lt;/strong&gt; module, để khám phá một cách để xây dựng &lt;strong&gt;DynamicDialog&lt;/strong&gt; mà không phải phụ thuộc vào bất cứ &lt;strong&gt;Bộ UI Component&lt;/strong&gt; nào để trong các dự án tương lai, bọn mình không phải lặp lại sai lầm nữa. Bài blog này là chia sẻ của mình về những gì mình tìm hiểu được và thông qua bài này, chúng ta sẽ sử dụng &lt;strong&gt;Angular CDK OverlayModule&lt;/strong&gt; cùng với &lt;strong&gt;Bulma CSS&lt;/strong&gt; để xây dựng một &lt;strong&gt;DynamicDialog&lt;/strong&gt; theo phong cách &lt;strong&gt;Angular&lt;/strong&gt;. Bắt đầu thôi.&lt;/p&gt;
&lt;h3 id=&quot;chuẩn-bị&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#chu%E1%BA%A9n-b%E1%BB%8B&quot; aria-label=&quot;chuẩn bị permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Chuẩn bị&lt;/h3&gt;
&lt;p&gt;Chúng ta sẽ bắt đầu bằng việc tạo mới một ứng dụng &lt;strong&gt;Angular&lt;/strong&gt; với &lt;strong&gt;Angular CLI&lt;/strong&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;69443892939864610000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng new cdk-bulma-dialog`, `69443892939864610000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng new cdk-bulma-dialog&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Nếu như chưa cài đặt &lt;strong&gt;Angular CLI&lt;/strong&gt;, các bạn cài bằng lệnh &lt;code class=&quot;language-text&quot;&gt;npm i -g @angular/cli&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/5bcc501ef0375ed4ebe214027cc68ee9/6150a/ngcli.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAAAsSAAALEgHS3X78AAABEklEQVQY02WP226CUBBF+ZZar4jFqihwuLfKTSuYWnixGPv/v7B6wDRN04eVmT3ZM5mt5FlNnGak+5gs35PvDxzejhyLgjTLsYWDH4SYtmCxXGFsNnfWLet/KEVZcLt9UdUffF4unM9nrteGpmm4SF2WJXVdsU0SHMdhMhnT6z3QHwwYDId/GI3HKOEuxo1eeHpe4G13bFwPIbXp+V0NkhQ/TggkUZrjSo+3S1jLz3VdR5/P78h9VZ2i+GHINo5lJJv3qiKTkU/yy+Pp1PWBPOpHEY4fIDwPNwgIXl4RrosQAkvu2W2VTFQVxTAMbDlcrladYWOanaGdWZaFpmk89vu/0WTUn7jD0aij7bXZDHU65Rvw36t7X1bLJwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;ngcli&quot;
        title=&quot;ngcli&quot;
        src=&quot;/static/5bcc501ef0375ed4ebe214027cc68ee9/1bed9/ngcli.png&quot;
        srcset=&quot;/static/5bcc501ef0375ed4ebe214027cc68ee9/7b64c/ngcli.png 160w,
/static/5bcc501ef0375ed4ebe214027cc68ee9/4e610/ngcli.png 320w,
/static/5bcc501ef0375ed4ebe214027cc68ee9/1bed9/ngcli.png 640w,
/static/5bcc501ef0375ed4ebe214027cc68ee9/6150a/ngcli.png 651w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Angular CLI khởi tạo một ứng dụng Angular mới&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Chúng ta sẽ &lt;strong&gt;không&lt;/strong&gt; cần &lt;code class=&quot;language-text&quot;&gt;routing&lt;/code&gt; và sẽ chọn &lt;code class=&quot;language-text&quot;&gt;SCSS&lt;/code&gt; cho phần giao diện. Kế tiếp, chúng ta sẽ cài &lt;strong&gt;Angular CDK&lt;/strong&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;85664296134176540000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng add @angular/cdk`, `85664296134176540000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng add @angular/cdk&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mở file &lt;code class=&quot;language-text&quot;&gt;styles.scss&lt;/code&gt; và thêm vào dòng code này:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;38895800424185140000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`@import &apos;~@angular/cdk/overlay-prebuilt.css&apos;;`, `38895800424185140000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;scss&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-scss line-numbers&quot;&gt;&lt;code class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;~@angular/cdk/overlay-prebuilt.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mở file &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt; và thêm &lt;code class=&quot;language-text&quot;&gt;BrowserAnimationsModule&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;88540567793783820000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { NgModule } from &apos;@angular/core&apos;;
import { BrowserModule } from &apos;@angular/platform-browser&apos;;
import { BrowserAnimationsModule } from &apos;@angular/platform-browser/animations&apos;; // &lt;-- thêm import này 
import { AppComponent } from &apos;./app.component&apos;;

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule, BrowserAnimationsModule], // &lt;-- thêm BrowserAnimationsModule
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {
}`, `88540567793783820000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserAnimationsModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- thêm import này &lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AppComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BrowserModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BrowserAnimationsModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- thêm BrowserAnimationsModule&lt;/span&gt;
  providers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bootstrap&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mở &lt;code class=&quot;language-text&quot;&gt;index.html&lt;/code&gt; và sửa lại như sau:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;41321525871512945000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;!doctype html&gt;
&lt;html lang=&amp;quot;en&amp;quot;&gt;
&lt;head&gt;
  &lt;meta charset=&amp;quot;utf-8&amp;quot;&gt;
  &lt;title&gt;CdkBulmaDialog&lt;/title&gt;
  &lt;base href=&amp;quot;/&amp;quot;&gt;
  &lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1&amp;quot;&gt;
  &lt;link rel=&amp;quot;icon&amp;quot; type=&amp;quot;image/x-icon&amp;quot; href=&amp;quot;favicon.ico&amp;quot;&gt;
    &lt;!-- Thêm BulmaCSS CDN --&gt;
  &lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css&amp;quot;&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;app-root&gt;&lt;/app-root&gt;
&lt;/body&gt;
&lt;/html&gt;`, `41321525871512945000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token doctype&quot;&gt;&amp;lt;!doctype html&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;en&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;utf-8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;CdkBulmaDialog&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;base&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meta&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;viewport&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;width=device-width, initial-scale=1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;icon&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;image/x-icon&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;favicon.ico&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Thêm BulmaCSS CDN --&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;app-root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;app-root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Và bây giờ thì chúng ta đã sẵn sàng để tiếp tục vào phần chính của bài blog này.&lt;/p&gt;
&lt;h3 id=&quot;nhiều-files-khác-nữa&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#nhi%E1%BB%81u-files-kh%C3%A1c-n%E1%BB%AFa&quot; aria-label=&quot;nhiều files khác nữa permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Nhiều Files khác nữa&lt;/h3&gt;
&lt;p&gt;Chúng ta sẽ bắt đầu phần này với việc khởi tạo một số files cần thiết bằng &lt;strong&gt;Angular CLI&lt;/strong&gt; lẫn bằng tay &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dùng &lt;strong&gt;Angular CLI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Khởi tạo &lt;code class=&quot;language-text&quot;&gt;DynamicDialogModule&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;28644463077694040000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate module dynamic-dialog`, `28644463077694040000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate module dynamic-dialog&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Khởi tạo &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;66688928302458910000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate service dynamic-dialog/dynamic-dialog --skipTests`, `66688928302458910000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate service dynamic-dialog/dynamic-dialog --skipTests&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Để bài viết này đơn giản, mình sẽ thêm &lt;code class=&quot;language-text&quot;&gt;skipTests&lt;/code&gt; vào tất cả các lệnh &lt;code class=&quot;language-text&quot;&gt;ng generate&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Khởi tạo &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;67510858696746620000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate directive dynamic-dialog/dynamic-dialog-content --skipTests`, `67510858696746620000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate directive dynamic-dialog/dynamic-dialog-content --skipTests&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Khởi tạo &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;22418392932284002000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng generate component dynamic-dialog/dynamic-dialog-root --flat --skipTests --inlineTemplate --inlineStyle`, `22418392932284002000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng generate component dynamic-dialog/dynamic-dialog-root --flat --skipTests --inlineTemplate --inlineStyle&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Chúng ta sẽ dùng &lt;code class=&quot;language-text&quot;&gt;inlineTemplate&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;inlineStyle&lt;/code&gt; để có thể thấy được những gì xảy ra trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; trong một file &lt;code class=&quot;language-text&quot;&gt;*.component.ts&lt;/code&gt; mà thôi.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Tạo thư mục và files bằng tay&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Chúng ta sẽ phải cần một số &lt;strong&gt;Models&lt;/strong&gt; nên các bạn hãy tự tạo một thư mục mới tên là &lt;code class=&quot;language-text&quot;&gt;models&lt;/code&gt;. Thư mục này nên nằm dưới &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog&lt;/code&gt; 1 bậc. &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;62787450254749460000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`# mặc định là các bạn đang ở root của cdk-bulma-dialog
cd src/app/dynamic-dialog
mkdir models
cd models`, `62787450254749460000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;# mặc định là các bạn đang ở root của cdk-bulma-dialog
cd src/app/dynamic-dialog
mkdir models
cd models&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bây giờ thì hãy tạo 1 số files sau&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;80568734900405500000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`touch animation-state.enum.ts
touch dynamic-dialog-config.model.ts`, `80568734900405500000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;touch animation-state.enum.ts
touch dynamic-dialog-config.model.ts&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;và cũng viết nốt code cho các files này luôn. Mở file &lt;code class=&quot;language-text&quot;&gt;animation-state.enum.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;57451359426424590000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export enum AnimationState {
  Void = &apos;void&apos;,
  Enter = &apos;enter&apos;,
  Leave = &apos;leave&apos;
}`, `57451359426424590000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Void &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;void&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Enter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;enter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Leave &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;leave&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;sau đó là &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-config.model.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;59192357192566194000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { OverlayConfig } from &apos;@angular/cdk/overlay&apos;;

export class DynamicDialogConfig&lt;TData = any&gt; {
  header: string;
  closable: boolean;
  containerAnimationTiming: number;
  contentAnimationTiming: number;
  animationChildDelay: number;
  data?: TData;
  overlayConfig?: OverlayConfig;

  constructor() {
    this.header = &apos;&apos;;
    this.closable = true;
    this.containerAnimationTiming = 0.3;
    this.contentAnimationTiming = 0.2;
    this.animationChildDelay = 0;
  }
}`, `59192357192566194000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; OverlayConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  header&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  closable&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  containerAnimationTiming&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  contentAnimationTiming&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  animationChildDelay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  data&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; TData&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  overlayConfig&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;header &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;closable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;containerAnimationTiming &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentAnimationTiming &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationChildDelay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hãy điểm qua từng &lt;code class=&quot;language-text&quot;&gt;config&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt;: Khá dễ hiểu. Chúng ta sẽ cấu hình &lt;code class=&quot;language-text&quot;&gt;dialog&lt;/code&gt; của mình để có một &lt;code class=&quot;language-text&quot;&gt;title&lt;/code&gt;. Mình sẽ cho phép người dùng &lt;strong&gt;Dialog&lt;/strong&gt; tuỳ chỉnh biến &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt; thông qua &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;closable&lt;/code&gt;: Cho phép &lt;strong&gt;Dialog&lt;/strong&gt; được đóng lại bằng cách: &lt;code class=&quot;language-text&quot;&gt;click vào backdrop&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;click vào close icon&lt;/code&gt;. Mặc định, chúng ta sẽ muốn có một &lt;code class=&quot;language-text&quot;&gt;close icon&lt;/code&gt; ở bên phải của &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;containerAnimationTiming&lt;/code&gt;: Thời gian để chạy animation của &lt;strong&gt;Dialog Container&lt;/strong&gt;. Nhìn trên màn hình, thì &lt;strong&gt;Dialog Container&lt;/strong&gt; sẽ là một khoảng có màu mờ, toàn màn hình và sẽ nằm bên dưới của &lt;strong&gt;Dialog Content&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;contentAnimationTiming&lt;/code&gt;: Thời gian để chạy animation của &lt;strong&gt;Dialog Content&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;animationChildDelay&lt;/code&gt;: Thời giản cách khoảng giữ animation của &lt;strong&gt;Dialog Conatiner` và **Dialog Content&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt;: Dữ liệu thêm để truyền vào cho &lt;strong&gt;Dialog&lt;/strong&gt; khi mở &lt;strong&gt;Dialog&lt;/strong&gt;. Phần lớn thì &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; sẽ chứa một số thông tin như &lt;code class=&quot;language-text&quot;&gt;productId&lt;/code&gt; chẳng hạn, để khi mở &lt;strong&gt;Dialog&lt;/strong&gt;, mình có thể dùng &lt;code class=&quot;language-text&quot;&gt;productId&lt;/code&gt; để fetch dữ liệu &lt;code class=&quot;language-text&quot;&gt;Product&lt;/code&gt;.  &lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;overlayConfig&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; của &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; từ &lt;strong&gt;Angular CDK&lt;/strong&gt;. &lt;strong&gt;Dialog&lt;/strong&gt; mà chúng ta đang dựng sẽ cấu hình một số giá trị mặc định cho &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; nhưng chúng ta cũng sẽ cung cấp người dùng &lt;strong&gt;Dialog&lt;/strong&gt; khả năng cấu hình &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; này thông qua biến &lt;code class=&quot;language-text&quot;&gt;overlayConfig&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;overlayConfig&lt;/code&gt; truyền vào sẽ được gộp (&lt;strong&gt;merge&lt;/strong&gt;) với config đã được cấu hình sẵn.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Kế đến, file cuối cùng mà chúng ta cần là &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;. Mình sẽ giải thích tầm quan trọng của &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt; khi chúng ta bắt đầu viết code cho nó. Bây giờ thì cứ tạo file đó đi đã.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;8870564759261623000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`# mặc định là các bạn đang ở bên trong src/app/dynamic-dialog/models
cd ..
touch dynamic-dialog-ref.ts`, `8870564759261623000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;# mặc định là các bạn đang ở bên trong src/app/dynamic-dialog/models
cd ..
touch dynamic-dialog-ref.ts&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;bắt-đầu-chiến-thôi&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#b%E1%BA%AFt-%C4%91%E1%BA%A7u-chi%E1%BA%BFn-th%C3%B4i&quot; aria-label=&quot;bắt đầu chiến thôi permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Bắt đầu chiến thôi&lt;/h3&gt;
&lt;p&gt;Đầu tiên, chúng ta sẽ xử lý thằng &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; trước vì nó rất ngắn và dễ hiểu. Mở file &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-content.directive.ts&lt;/code&gt; lên thôi&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;55364451637927130000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Directive, ViewContainerRef } from &apos;@angular/core&apos;;

@Directive({
  selector: &apos;[appDynamicDialogContent]&apos;
})
export class DynamicDialogContentDirective {

  constructor(public readonly viewContainerRef: ViewContainerRef) { } // &lt;-- inject ViewContainerRef

}`, `55364451637927130000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ViewContainerRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[appDynamicDialogContent]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogContentDirective&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; viewContainerRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ViewContainerRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- inject ViewContainerRef&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Thằng &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; này sẽ giữ vai trò như một &lt;strong&gt;cột mốc để thêm vào&lt;/strong&gt;. Đây là nơi mà chúng ta muốn hiển thị động &lt;code class=&quot;language-text&quot;&gt;nội dung&lt;/code&gt; (bằng một &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt;) của &lt;strong&gt;Dialog&lt;/strong&gt;. Vì vậy, chúng ta cần inject &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; vào thằng &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; này để khi nó được mount, nó sẽ có quyền truy xuất đến cái element gốc mà &lt;code class=&quot;language-text&quot;&gt;directive&lt;/code&gt; này được sử dụng trên element gốc đó dưới dạng là &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt;. (Đọc thêm về &lt;a href=&quot;https://angular.io/api/core/Directive&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular Directive&lt;/a&gt;). Đừng lo lắng nếu nghe như sét đánh ngang tai, chúng ta sẽ gỡ các nút thắt sớm thôi. &lt;/p&gt;
&lt;p&gt;và đó là tất cả code mà chúng ta cần cho &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;. Giờ thì mở file &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-ref.ts&lt;/code&gt; và thêm 1 đoạn code nhỏ này&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;62155183661297440000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`export class DynamicDialogRef&lt;TReturnType = any&gt; {

}`, `62155183661297440000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hiện tại thì chỉ cần nhiêu đó thôi. Giờ hãy mở file &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog-root.component.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;33961924303662960000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AfterViewInit, ChangeDetectionStrategy, Component, OnDestroy } from &apos;@angular/core&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;p&gt;
      dynamic-dialog-root works!
    &lt;/p&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush // &lt;-- dùng OnPush strategy.
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy { // &lt;-- implements AfterViewInit and OnDestroy

  constructor() {
  }

  ngAfterViewInit(): void { // &lt;-- ngAfterViewInit
  }

  ngOnDestroy(): void { // &lt;-- ngOnDestroy
  }
}`, `33961924303662960000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;p&gt;
      dynamic-dialog-root works!
    &amp;lt;/p&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- dùng OnPush strategy.&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- implements AfterViewInit and OnDestroy&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- ngAfterViewInit&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- ngOnDestroy&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Chúng ta sẽ cần một số fields sau:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;animationState&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt;: Dùng để theo dõi các bước animations của &lt;code class=&quot;language-text&quot;&gt;container&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt; của &lt;strong&gt;Dialog&lt;/strong&gt;. Chúng ta sẽ dựa vào &lt;code class=&quot;language-text&quot;&gt;animationState&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;AnimationEvent&lt;/code&gt; từ gói &lt;code class=&quot;language-text&quot;&gt;@angular/animations&lt;/code&gt; để xác định được thời điểm mà &lt;strong&gt;Dialog&lt;/strong&gt; bị đóng lại.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; được truyền vào và được dùng để hiển thị phần &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt; của &lt;strong&gt;Dialog&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;componentRef&lt;/code&gt;: Biến này chỉ dùng để giữ con trỏ hiện tại đến &lt;strong&gt;Dialog Content Component&lt;/strong&gt;, được dùng để “dọn dẹp”, tiêu huỷ đi khi hook &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy&lt;/code&gt; chạy. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Quẩy code cho mấy fields này thôi&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;98615029333436960000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;; // &lt;-- import AnimationState

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;p&gt;
      dynamic-dialog-root works!
    &lt;/p&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    animationState: AnimationState = AnimationState.Enter;
    // Bảo đảm là các bạn import AnimationEvent từ @angular/animations
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

  constructor() {
  }

  ngAfterViewInit(): void {
  }

  ngOnDestroy(): void {
  }
}`, `98615029333436960000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- import AnimationState&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;p&gt;
      dynamic-dialog-root works!
    &amp;lt;/p&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Bảo đảm là các bạn import AnimationEvent từ @angular/animations&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ngoài những fields trên, chúng ta cũng sẽ cần một số thứ được injected vào cho &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; này thông qua &lt;strong&gt;Dependency Injection (DI)&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;: Hàng &lt;code class=&quot;language-text&quot;&gt;configuration&lt;/code&gt; hand-made của mình&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;: Hàng &lt;code class=&quot;language-text&quot;&gt;dialogRef&lt;/code&gt; hand-made của mình&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ComponentFactoryResolver&lt;/code&gt;: Một chút kiến thức chung. Khi các bạn khởi tạo và sử dụng một &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; thông thường bên trong &lt;strong&gt;Angular&lt;/strong&gt; (nghĩa là dùng &lt;code class=&quot;language-text&quot;&gt;selector&lt;/code&gt; của &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;template&lt;/code&gt;. Ví dụ: &lt;code class=&quot;language-text&quot;&gt;&amp;lt;app-todo-item&amp;gt;&amp;lt;/app-todo-item&amp;gt;&lt;/code&gt;), &lt;strong&gt;Angular&lt;/strong&gt; sẽ lấy thông tin metadata từ decorator &lt;code class=&quot;language-text&quot;&gt;@Component()&lt;/code&gt; và sẽ tạo một &lt;code class=&quot;language-text&quot;&gt;factory&lt;/code&gt; cho &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; đó. &lt;code class=&quot;language-text&quot;&gt;Factory&lt;/code&gt; sau đó sẽ được &lt;strong&gt;Angular Compiler&lt;/strong&gt; dùng để biết được thông tin về &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt;, từ đó sẽ hiển thị cũng như cung cấp những thứ cần thiết cho &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; đó sử dụng. &lt;strong&gt;Dialog&lt;/strong&gt; của mình sẽ được hiển thị động trên màn hình vào bất cứ thời điểm nào. Vì thế, chúng ta sẽ cần phải dùng đến &lt;code class=&quot;language-text&quot;&gt;ComponentFactoryResolver&lt;/code&gt; để có thể tạo được &lt;code class=&quot;language-text&quot;&gt;factory&lt;/code&gt; cho &lt;strong&gt;Dialog&lt;/strong&gt; bằng tay.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ChangeDetectorRef&lt;/code&gt;: Ý tưởng ở đây là chúng ta sẽ bắt đầu việc khởi tạo &lt;strong&gt;Dialog Content Component&lt;/strong&gt; trong hook &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit&lt;/code&gt; sau khi &lt;strong&gt;DOM&lt;/strong&gt; ban đầu đã được load xong. Bên cạnh đó, chúng ta cũng sử dụng &lt;code class=&quot;language-text&quot;&gt;OnPush&lt;/code&gt; vì thế sau khi khởi tạo &lt;strong&gt;Dialog Content Component&lt;/strong&gt;, chúng ta sẽ muốn gọi &lt;code class=&quot;language-text&quot;&gt;changeDetectorRef.markForCheck()&lt;/code&gt; để thông báo cho &lt;strong&gt;Cơ chế Change Detection của Angular&lt;/strong&gt; biến được có sự thay đổi trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; và việc thông báo này chỉ xảy ra một lần duy nhất thôi. Các thay đổi khác trong tương lai sẽ xảy ra bên trong &lt;strong&gt;Dialog Content Component&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Một lần nữa, quẩy code thôi&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;86923953541378670000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;p&gt;
      dynamic-dialog-root works!
    &lt;/p&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

  constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
  }

  ngAfterViewInit(): void {
  }

  ngOnDestroy(): void {
  }
}`, `86923953541378670000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;p&gt;
      dynamic-dialog-root works!
    &amp;lt;/p&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quẩy &lt;code class=&quot;language-text&quot;&gt;template&lt;/code&gt; nào&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;29873928646295278000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    // Giữ lấy con trỏ tới Directive để dùng trong TypeScript
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
    }

    ngOnDestroy(): void {
    }
}`, `29873928646295278000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Giữ lấy con trỏ tới Directive để dùng trong TypeScript&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Mình lấy &lt;code class=&quot;language-text&quot;&gt;HTML&lt;/code&gt; trực tiếp từ &lt;a href=&quot;https://bulma.io/documentation/components/modal/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Bulma Modal&lt;/a&gt; luôn và chỉ thay đổi &lt;code class=&quot;language-text&quot;&gt;Modal Title&lt;/code&gt; sang &lt;code class=&quot;language-text&quot;&gt;dialogConfig.header&lt;/code&gt;. Mình cũng bỏ tất cả những thứ râu ria ở giữa &lt;code class=&quot;language-text&quot;&gt;&amp;lt;section class=&amp;quot;modal-card-body&amp;quot;&amp;gt;&amp;lt;/section&amp;gt;&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ng-template&amp;gt;&amp;lt;/ng-template&amp;gt;&lt;/code&gt; và quăng thằng &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; lên &lt;code class=&quot;language-text&quot;&gt;ng-tempalte&lt;/code&gt;. Nếu bạn nào đã biết các &lt;strong&gt;Dynamic Component&lt;/strong&gt; hoạt động trong &lt;strong&gt;Angular&lt;/strong&gt;, bạn có thể thấy được cái gì đang xảy ra ở đây rồi. Chúng ta dùng &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt;, bind &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt; lên &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt;, và nếu nhớ lại, thì chúng ta cũng inject &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;. Tất cả mấy thứ này sẽ giúp chúng ta lấy được con trỏ tới &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt; dưới dạng &lt;code class=&quot;language-text&quot;&gt;ViewContainerRef&lt;/code&gt; và chuyển &lt;code class=&quot;language-text&quot;&gt;ng-template&lt;/code&gt; này thành &lt;strong&gt;cột mốc&lt;/strong&gt; để có thể hiển thị động &lt;strong&gt;Dialog Content Component&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Bây giờ thì triển code cho &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit()&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy()&lt;/code&gt; thôi&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;75215858760207140000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }
}`, `75215858760207140000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Như đã nhắc ở trên, trong &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit()&lt;/code&gt;, chúng ta sẽ khởi tạo &lt;strong&gt;Dialog Content Component&lt;/strong&gt; bằng việc gọi hàm &lt;code class=&quot;language-text&quot;&gt;loadContentComponent()&lt;/code&gt;, dùng &lt;code class=&quot;language-text&quot;&gt;ComponentFactoryResolver&lt;/code&gt; và sẽ thông báo cho &lt;strong&gt;Change Detection&lt;/strong&gt; để có thể update &lt;strong&gt;DialogRootComponent&lt;/strong&gt; sau khi khởi tạo xong. Trong hàm &lt;code class=&quot;language-text&quot;&gt;loadContentComponent()&lt;/code&gt;, chúng ta cũng sẽ lấy &lt;code class=&quot;language-text&quot;&gt;viewContainerRef&lt;/code&gt; từ thằng &lt;code class=&quot;language-text&quot;&gt;DynamicDialogContentDirective&lt;/code&gt;. Nếu để ý, các bạn sẽ thấy là mình chưa bao giờ gán giá trị cho &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; ở đâu trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; hết, và các bạn hoàn toàn đúng. Chúng ta sẽ gán giá trị cho &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; vào một thời điểm “sớm” hơn, và ở một vị trí khác. Trong &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy()&lt;/code&gt;, chúng ta chỉ triển khai một số công việc dọn dẹp với &lt;code class=&quot;language-text&quot;&gt;componentRef&lt;/code&gt; thôi. Khá là dễ hiểu 😊. Trước khi chuyển sang file khác, hãy triển thêm 1 hàm cho &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; nữa.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;9996627131775738000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    // Thêm hàm này
    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }
}`, `9996627131775738000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Thêm hàm này&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Các bạn có nhớ mình nói là chúng ta sẽ dùng đến &lt;code class=&quot;language-text&quot;&gt;animationState&lt;/code&gt; để quyết định việc đóng &lt;strong&gt;Dialog&lt;/strong&gt; không? Hàm &lt;code class=&quot;language-text&quot;&gt;startExitAnimation()&lt;/code&gt; sẽ giúp chúng ta bắt đầu được quy trình đóng &lt;strong&gt;Dialog&lt;/strong&gt; này. Phù, vẫn có một số việc cần phải làm trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; nữa, nhưng chúng ta sẽ phải quay lại file này sau. Điểm đến kế tiếp sẽ là &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;, con hàng quan trọng không kém 💪&lt;/p&gt;
&lt;h3 id=&quot;dynamicdialogref&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dynamicdialogref&quot; aria-label=&quot;dynamicdialogref permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;DynamicDialogRef&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; là một con trỏ đến instance hiện tại của &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; đang được mở (và được quản lý bởi &lt;strong&gt;Angular CDK&lt;/strong&gt;). Chúng ta sẽ cần một số fields và hàm trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; sau:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt;: Đây là một &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; này sẽ emit khi &lt;strong&gt;Dialog&lt;/strong&gt; &lt;strong&gt;chuẩn bị&lt;/strong&gt; được đóng. Chúng ta sẽ giữ cho &lt;code class=&quot;language-text&quot;&gt;Subject&lt;/code&gt; này &lt;code class=&quot;language-text&quot;&gt;private&lt;/code&gt; và sẽ chỉ cung cấp cho người dùng phần &lt;code class=&quot;language-text&quot;&gt;Observable&lt;/code&gt; thông qua một &lt;code class=&quot;language-text&quot;&gt;getter&lt;/code&gt; mà thôi.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt;: Tương tự như &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt;. Khi &lt;strong&gt;Dialog&lt;/strong&gt; đã được đóng lại, thì chúng ta sẽ truyền kèm theo một số &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; (nếu có) mà người dùng muốn truyền.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt;: Instane của &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; đang được sử dụng bởi &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; để hiển thị &lt;strong&gt;Dialog&lt;/strong&gt;. Chúng ta sẽ cần tới &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; và hàm &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt; của hắn để có thể xác định được đúng thời điểm mà &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt; cần emit.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;close(data?: TReturnType)&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; sẽ được đưa vào &lt;strong&gt;Dependency Injection&lt;/strong&gt; bằng &lt;strong&gt;Injector&lt;/strong&gt; để người dùng có thể inject &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; vào &lt;strong&gt;Dialog Content Component&lt;/strong&gt; mà họ tạo và sẽ gọi được hàm &lt;code class=&quot;language-text&quot;&gt;dialogRef.close()&lt;/code&gt; này. Ví dụ: khi người dùng đóng một &lt;strong&gt;Dialog Xác Nhận&lt;/strong&gt;, chúng ta sẽ muốn biết được là người dùng chọn &lt;strong&gt;Xác Nhận&lt;/strong&gt; hay &lt;strong&gt;Huỷ bỏ&lt;/strong&gt; khi &lt;strong&gt;Dialog&lt;/strong&gt; được đóng, vì thế tuỳ thuộc vào lựa chọn của người dùng mà chúng ta có thể truyền &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; vào cho hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; để nơi mở &lt;strong&gt;Dialog&lt;/strong&gt; (&lt;strong&gt;Dialog Invoker&lt;/strong&gt;) có thể nhận được &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; này và thực thi thao tác tiếp theo sau khi người dùng &lt;strong&gt;Xác Nhận&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ngoài 4 thứ trên, chúng ta cũng sẽ cần inject &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; từ &lt;strong&gt;Angular CDK&lt;/strong&gt; để có thể thực hiện một số tác vụ dọn dẹp trên thằng &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt;. Giờ thì quẩy code thôi.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;18294952432738310000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { Observable, Subject } from &apos;rxjs&apos;;
import { filter, take } from &apos;rxjs/operators&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;

// Hằng số local.
const AnimationPhase = {
  START: &apos;start&apos;,
  DONE: &apos;done&apos;
};

export class DynamicDialogRef&lt;TReturnType = any&gt; {
  private beforeClosed\$: Subject&lt;void&gt; = new Subject&lt;void&gt;();
  private afterClosed\$: Subject&lt;TReturnType&gt; = new Subject&lt;TReturnType&gt;();

  componentInstance: DynamicDialogRootComponent;

  constructor(private readonly overlayRef: OverlayRef) {
        overlayRef.backdropClick().pipe(take(1)).subscribe(this.close.bind(this));
  }

  get beforeClosed(): Observable&lt;void&gt; {
    return this.beforeClosed\$.asObservable();
  }

  get afterClosed(): Observable&lt;TReturnType&gt; {
    return this.afterClosed\$.asObservable();
  }

  close(data?: TReturnType): void {
    this.componentInstance.animationStateChanged.pipe(
      filter(event =&gt; event.phaseName === AnimationPhase.START),
      take(1)
    ).subscribe(() =&gt; {
      this.beforeClosed\$.next();
      this.beforeClosed\$.complete();
      this.overlayRef.detachBackdrop();
    });

    this.componentInstance.animationStateChanged.pipe(
      filter(event =&gt; event.phaseName === AnimationPhase.DONE &amp;&amp; event.toState === AnimationState.Leave),
      take(1)
    ).subscribe(() =&gt; {
      this.overlayRef.dispose();
      this.afterClosed\$.next(data);
      this.afterClosed\$.complete();
      this.componentInstance = null;
    });

    this.componentInstance.startExitAnimation();
  }
}`, `18294952432738310000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Observable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Subject &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rxjs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; filter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; take &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;rxjs/operators&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Hằng số local.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; AnimationPhase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;START&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;start&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;DONE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; beforeClosed$&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Subject&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; afterClosed$&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Subject&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Subject&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  componentInstance&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlayRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;backdropClick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;beforeClosed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;beforeClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;asObservable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;afterClosed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;asObservable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; TReturnType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationStateChanged&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phaseName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; AnimationPhase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;START&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;beforeClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;beforeClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;detachBackdrop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationStateChanged&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pipe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phaseName &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; AnimationPhase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DONE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;toState &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;take&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dispose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Quá trời thứ xảy ra ở đây. Hãy đi qua từng cái một nhé.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;AnimationPhase&lt;/code&gt; chỉ là một hằng số local thôi. Thay vì dùng magic-string &lt;code class=&quot;language-text&quot;&gt;&amp;#39;start&amp;#39;&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;&amp;#39;done&amp;#39;&lt;/code&gt; thì mình dùng &lt;code class=&quot;language-text&quot;&gt;AnimationPhase&lt;/code&gt;. Nếu muốn, bạn có thể đem &lt;code class=&quot;language-text&quot;&gt;AnimationPhase&lt;/code&gt; ra một file riêng cũng được.&lt;/li&gt;
&lt;li&gt;Trong &lt;code class=&quot;language-text&quot;&gt;constructor&lt;/code&gt;, chúng ta sẽ lắng nghe thằng &lt;code class=&quot;language-text&quot;&gt;backdropClick()&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;overlayRef&lt;/code&gt; và sẽ gọi hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; khi &lt;code class=&quot;language-text&quot;&gt;backdrop&lt;/code&gt; được &lt;code class=&quot;language-text&quot;&gt;click&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Khai báo tất cả các fields được nhắc đến ở trên: &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt;, mấy cái &lt;code class=&quot;language-text&quot;&gt;getters&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; được inject, và hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt;: con hàng quan trọng của &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;. Trong đây, chúng ta xác lập 2 &lt;code class=&quot;language-text&quot;&gt;Subscriptions&lt;/code&gt; đến &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt;: Một cái là sẽ lắng nghe &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.START&lt;/code&gt; và cái còn lại là lắng nghe &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.DONE&lt;/code&gt;. Khi chúng ta bắt đầu gọi hàm &lt;code class=&quot;language-text&quot;&gt;closse()&lt;/code&gt;,
thì thực tế các animations của &lt;strong&gt;Dialog&lt;/strong&gt; sẽ bắt đầu chạy trước và &lt;code class=&quot;language-text&quot;&gt;@angular/animations&lt;/code&gt; cho phép chúng ta lắng nghe những &lt;code class=&quot;language-text&quot;&gt;AnimationEvent&lt;/code&gt; này. Trong quá trình &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.START&lt;/code&gt; (animations bắt đầu) chạy, chúng ta &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt; các sự kiện &lt;code class=&quot;language-text&quot;&gt;Animation&lt;/code&gt; này theo &lt;code class=&quot;language-text&quot;&gt;phaseName&lt;/code&gt; và chúng ta cũng chỉ cần nhận giá trị của &lt;strong&gt;MỘT&lt;/strong&gt; sự kiện duy nhât mà thôi nên chúng ta dùng &lt;code class=&quot;language-text&quot;&gt;take(1)&lt;/code&gt;. Ở thời điểm này, &lt;code class=&quot;language-text&quot;&gt;beforeClosed$&lt;/code&gt; sẽ emit và cũng sẽ tự hoàn thành để tự dọn dẹp luôn. Cuối cùng ở chuỗi sự kiến &lt;code class=&quot;language-text&quot;&gt;AnimationPhase.START&lt;/code&gt;, chúng ta sẽ gọi hàm &lt;code class=&quot;language-text&quot;&gt;overlayRef.detachBackdrop()&lt;/code&gt; để dọn dẹp thằng &lt;code class=&quot;language-text&quot;&gt;backdrop&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Subscription&lt;/code&gt; còn lại thì chúng ta cũng dùng các bước tương tự, &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt; bằng &lt;code class=&quot;language-text&quot;&gt;phaseName&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;take(1)&lt;/code&gt; và cho &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt; emit. Khác biệt ở đây là chúng ta sẽ gọi &lt;code class=&quot;language-text&quot;&gt;overlayRef.dispose()&lt;/code&gt; để dọn dẹp thằng &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; trước, sau đó sẽ cho &lt;code class=&quot;language-text&quot;&gt;afterClosed$&lt;/code&gt; emit &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; mà người dùng cần rồi hoàn tất. Ở cuối chuỗi sự kiện, chúng ta sẽ dọn dẹp luôn thằng &lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt; bằng cách gán &lt;code class=&quot;language-text&quot;&gt;null&lt;/code&gt; cho nó, vì chúng ta không cần nó nữa.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Các bạn lưu ý ở đây là &lt;strong&gt;RxJS&lt;/strong&gt; là asynchronous (bất đồng bộ). Chúng ta chỉ mới thiết lập 2 &lt;code class=&quot;language-text&quot;&gt;Subscriptions&lt;/code&gt; mà thôi, code ở trong 2 &lt;code class=&quot;language-text&quot;&gt;Subscriptions&lt;/code&gt; này sẽ không được thực thi ngay lập tức khi hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt; được gọi. Đây chỉ gọi là “khâu chuẩn bị” mà thôi.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sau khi chuẩn bị xong các &lt;code class=&quot;language-text&quot;&gt;Subscriptions&lt;/code&gt;, thì chúng ta gọi &lt;code class=&quot;language-text&quot;&gt;componentInstance.startExitAnimation()&lt;/code&gt; để bắt đầu chuỗi sự kiện đóng &lt;strong&gt;Dialog&lt;/strong&gt;. &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; đã hoàn tất. Bây giờ chúng ta sẽ quay lại &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; để hoàn tất nó luôn.&lt;/p&gt;
&lt;h3 id=&quot;hoàn-tất-dynamicdialogrootcomponent&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#ho%C3%A0n-t%E1%BA%A5t-dynamicdialogrootcomponent&quot; aria-label=&quot;hoàn tất dynamicdialogrootcomponent permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Hoàn tất DynamicDialogRootComponent&lt;/h3&gt;
&lt;p&gt;Đầu tiên thì hãy thiết lập một số hàm mà sẽ gọi &lt;code class=&quot;language-text&quot;&gt;dynamicDialogRef.close()&lt;/code&gt; mặc định.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;48557098078466910000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { AnimationEvent } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild,
    HostListener
} from &apos;@angular/core&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;; // &lt;-- import AnimationState
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }

    closeDialog() {
        this.dialogRef.close();
    }

    @HostListener(&amp;quot;document:keydown&amp;quot;, [&amp;quot;\$event.key&amp;quot;])
    private handleEscapeKey(key: string) {
        if (key === &apos;Escape&apos;) {
          this.closeDialog();
        }
    }
}`, `48557098078466910000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationEvent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    HostListener
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- import AnimationState&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;document:keydown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$event.key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEscapeKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Escape&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Chúng ta thêm vào 2 hàm mới &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;closeDialog()&lt;/code&gt;: Xử lý việc đóng &lt;strong&gt;Dialog&lt;/strong&gt; khi &lt;code class=&quot;language-text&quot;&gt;backdrop&lt;/code&gt; hoặc &lt;code class=&quot;language-text&quot;&gt;close icon&lt;/code&gt; được click.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;handleEscapeKey()&lt;/code&gt;: Xử lý đóng &lt;strong&gt;Dialog&lt;/strong&gt; khi phím Escape được bấm bằng việc dùng &lt;code class=&quot;language-text&quot;&gt;HostListener&lt;/code&gt; lắng nghe sự kiện &lt;code class=&quot;language-text&quot;&gt;document:keydown&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Giờ thì chúng ta sẽ thêm &lt;code class=&quot;language-text&quot;&gt;animations&lt;/code&gt; vào cho &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mình sẽ dùng một gói npm tên là &lt;code class=&quot;language-text&quot;&gt;ng-animate&lt;/code&gt; để hỗ trợ khả năng animations dở ẹc của mình. Nếu các bạn muốn thì hãy cài &lt;code class=&quot;language-text&quot;&gt;ng-animate&lt;/code&gt; bằng lệnh &lt;code class=&quot;language-text&quot;&gt;npm i ng-animate&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;65878244480294560000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { animateChild, AnimationEvent, group, query, transition, trigger, useAnimation } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild,
    HostListener
} from &apos;@angular/core&apos;;
import { fadeIn, fadeOut, zoomIn, zoomOut } from &apos;ng-animate&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot;&gt;&lt;/div&gt;
      &lt;div class=&amp;quot;modal-card&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  \`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [
    trigger(&apos;zoom&apos;, [
      transition(
        &apos;* =&gt; in&apos;,
        useAnimation(zoomIn, { params: { timing: &apos;{{timing}}&apos; } })
      ),
      transition(
        &apos;* =&gt; out&apos;,
        useAnimation(zoomOut, { params: { timing: &apos;{{timing}}&apos; } })
      )
    ]),
    trigger(&apos;animation&apos;, [
      transition(
        \`* =&gt; \${ AnimationState.Enter }\`,
        group([
          useAnimation(fadeIn, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      ),
      transition(
        \`* =&gt; \${ AnimationState.Leave }\`,
        group([
          useAnimation(fadeOut, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      )
    ])
  ]
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }

    closeDialog() {
        this.dialogRef.close();
    }

    @HostListener(&amp;quot;document:keydown&amp;quot;, [&amp;quot;\$event.key&amp;quot;])
    private handleEscapeKey(key: string) {
        if (key === &apos;Escape&apos;) {
          this.closeDialog();
        }
    }
}`, `65878244480294560000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; animateChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AnimationEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; group&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; transition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; trigger&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useAnimation &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    HostListener
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomOut &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ng-animate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div class=&quot;modal-card&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; in&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; out&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;animation&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;document:keydown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$event.key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEscapeKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Escape&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ok, giờ giải thích mới dã man đây. Trước tiên thì mình xin gợi ý các bạn đọc thêm về &lt;a href=&quot;https://angular.io/guide/animations&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular Animations&lt;/a&gt; để không hoang mang, vì mình giải thích animations không được tốt. Về căn bản, chúng ta thiết lập 2 animations: &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; sẽ chịu trách nhiệm animating thằng &lt;strong&gt;Dialog Content&lt;/strong&gt; trong khi &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; sẽ chịu trách nhiệm cho thằng &lt;strong&gt;Dialog Container&lt;/strong&gt;. Ở trong &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt;, chúng ta thiết lập &lt;code class=&quot;language-text&quot;&gt;fadeIn&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;fadeOut&lt;/code&gt; được dựng sẵn (từ &lt;code class=&quot;language-text&quot;&gt;ng-animate&lt;/code&gt;, nếu các bạn tự viết &lt;strong&gt;Animations&lt;/strong&gt; thoải mái, thì cứ việc tự viết nhé) dựa vào &lt;code class=&quot;language-text&quot;&gt;state&lt;/code&gt;, chúng ta cũng sẽ dùng đến &lt;code class=&quot;language-text&quot;&gt;Animation Params&lt;/code&gt; (ví dụ: &lt;code class=&quot;language-text&quot;&gt;{{timing}}&lt;/code&gt;) để có thể truyền các tham số liên quan đến &lt;code class=&quot;language-text&quot;&gt;Animation&lt;/code&gt; vào trong các animations này. Các bạn có nhớ &lt;code class=&quot;language-text&quot;&gt;containerAnimationTiming&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;contentAnimationTiming&lt;/code&gt; không? Được dùng ở đây nè. Cuối cùng, chúng ta cũng thiết lập &lt;code class=&quot;language-text&quot;&gt;query&lt;/code&gt; cho &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; bên trong &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; để chúng ta có thể chạy được &lt;code class=&quot;language-text&quot;&gt;animationChild&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;delay&lt;/code&gt;. Ví dụ muốn chạy animation cho &lt;code class=&quot;language-text&quot;&gt;container&lt;/code&gt; xong, đợi một chút rồi mới chạy animation của &lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt;?! Một lần nữa, mình tha thiết mong các bạn đọc qua &lt;strong&gt;Angular Animations&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Giờ thì hoàn tất thằng &lt;code class=&quot;language-text&quot;&gt;template&lt;/code&gt; để kết nối các hàm và animations vừa thiết lập xong &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;75485296211448480000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { animateChild, AnimationEvent, group, query, transition, trigger, useAnimation } from &apos;@angular/animations&apos;;
import { 
    AfterViewInit, 
    ChangeDetectionStrategy, 
    Component, 
    OnDestroy, 
    EventEmitter,
    Type,
    ComponentRef,
    ComponentFactoryResolver,
    ChangeDetectorRef,
    ViewChild,
    HostListener
} from &apos;@angular/core&apos;;
import { fadeIn, fadeOut, zoomIn, zoomOut } from &apos;ng-animate&apos;;
import { AnimationState } from &apos;./models/animation-state.enum&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;

@Component({
  selector: &apos;app-dynamic-dialog-root&apos;,
  template: \`
    &lt;div
      class=&amp;quot;modal is-active&amp;quot;
      style=&amp;quot;padding-left: 1rem; padding-right: 1rem&amp;quot;
      [@animation]=&amp;quot;{
        value: animationState,
        params: {
          timing: dialogConfig.containerAnimationTiming,
          delayChild: dialogConfig.animationChildDelay
        }
      }&amp;quot;
      (@animation.start)=&amp;quot;animationStateChanged.emit(\$event)&amp;quot;
      (@animation.done)=&amp;quot;animationStateChanged.emit(\$event)&amp;quot;
    &gt;
      &lt;div class=&amp;quot;modal-background&amp;quot; (click)=&amp;quot;closeDialog()&amp;quot;&gt;&lt;/div&gt;
      &lt;div
        class=&amp;quot;modal-card&amp;quot;
        [@zoom]=&amp;quot;{
          value: animationState == &apos;enter&apos; ? &apos;in&apos; : &apos;out&apos;,
          params: { timing: dialogConfig.contentAnimationTiming }
        }&amp;quot;&gt;
        &lt;header class=&amp;quot;modal-card-head&amp;quot;&gt;
          &lt;p class=&amp;quot;modal-card-title&amp;quot;&gt;{{ dialogConfig.header }}&lt;/p&gt;
          &lt;button
            class=&amp;quot;delete&amp;quot;
            aria-label=&amp;quot;close&amp;quot;
            *ngIf=&amp;quot;dialogConfig.closable&amp;quot;
            (click)=&amp;quot;closeDialog()&amp;quot;
          &gt;&lt;/button&gt;
        &lt;/header&gt;
        &lt;section class=&amp;quot;modal-card-body&amp;quot;&gt;
          &lt;ng-template appDynamicDialogContent&gt;&lt;/ng-template&gt;
        &lt;/section&gt;
      &lt;/div&gt;
    &lt;/div&gt;
\`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  animations: [
    trigger(&apos;zoom&apos;, [
      transition(
        &apos;* =&gt; in&apos;,
        useAnimation(zoomIn, { params: { timing: &apos;{{timing}}&apos; } })
      ),
      transition(
        &apos;* =&gt; out&apos;,
        useAnimation(zoomOut, { params: { timing: &apos;{{timing}}&apos; } })
      )
    ]),
    trigger(&apos;animation&apos;, [
      transition(
        \`* =&gt; \${ AnimationState.Enter }\`,
        group([
          useAnimation(fadeIn, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      ),
      transition(
        \`* =&gt; \${ AnimationState.Leave }\`,
        group([
          useAnimation(fadeOut, { params: { timing: &apos;{{timing}}&apos; } }),
          query(&apos;@zoom&apos;, [animateChild({ delay: &apos;{{delayChild}}&apos; })], { optional: true })
        ])
      )
    ])
  ]
})
export class DynamicDialogRootComponent implements AfterViewInit, OnDestroy {
    @ViewChild(DynamicDialogContentDirective, { static: false }) contentInsertionPoint: DynamicDialogContentDirective;

    animationState: AnimationState = AnimationState.Enter;
    animationStateChanged: EventEmitter&lt;AnimationEvent&gt; = new EventEmitter&lt;AnimationEvent&gt;();
    contentComponentType: Type&lt;any&gt;;
    
    private componentRef: ComponentRef&lt;any&gt;;

    constructor(
        public readonly dialogConfig: DynamicDialogConfig,
        private readonly dialogRef: DynamicDialogRef,
        private readonly cfr: ComponentFactoryResolver,
        private readonly cdr: ChangeDetectorRef
    ) {
    }

    ngAfterViewInit(): void {
        this.loadContentComponent();
        this.cdr.markForCheck();
    }

    ngOnDestroy(): void {
        if (this.componentRef) {
          this.componentRef.destroy();
        }
    }

    startExitAnimation(): void {
        this.animationState = AnimationState.Leave;
    }

    private loadContentComponent(): void {
        const factory = this.cfr.resolveComponentFactory(this.contentComponentType);
        const vcr = this.contentInsertionPoint.viewContainerRef;
        vcr.clear();
        this.componentRef = vcr.createComponent(factory);
    }

    closeDialog() {
        this.dialogRef.close();
    }

    @HostListener(&amp;quot;document:keydown&amp;quot;, [&amp;quot;\$event.key&amp;quot;])
    private handleEscapeKey(key: string) {
        if (key === &apos;Escape&apos;) {
          this.closeDialog();
        }
    }
}`, `75485296211448480000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; animateChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AnimationEvent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; group&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; transition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; trigger&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useAnimation &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
    EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    Type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ChangeDetectorRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ViewChild&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    HostListener
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; zoomOut &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ng-animate&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnimationState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/animation-state.enum&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-dynamic-dialog-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;div
      class=&quot;modal is-active&quot;
      style=&quot;padding-left: 1rem; padding-right: 1rem&quot;
      [@animation]=&quot;{
        value: animationState,
        params: {
          timing: dialogConfig.containerAnimationTiming,
          delayChild: dialogConfig.animationChildDelay
        }
      }&quot;
      (@animation.start)=&quot;animationStateChanged.emit($event)&quot;
      (@animation.done)=&quot;animationStateChanged.emit($event)&quot;
    &gt;
      &amp;lt;div class=&quot;modal-background&quot; (click)=&quot;closeDialog()&quot;&gt;&amp;lt;/div&gt;
      &amp;lt;div
        class=&quot;modal-card&quot;
        [@zoom]=&quot;{
          value: animationState == &apos;enter&apos; ? &apos;in&apos; : &apos;out&apos;,
          params: { timing: dialogConfig.contentAnimationTiming }
        }&quot;&gt;
        &amp;lt;header class=&quot;modal-card-head&quot;&gt;
          &amp;lt;p class=&quot;modal-card-title&quot;&gt;{{ dialogConfig.header }}&amp;lt;/p&gt;
          &amp;lt;button
            class=&quot;delete&quot;
            aria-label=&quot;close&quot;
            *ngIf=&quot;dialogConfig.closable&quot;
            (click)=&quot;closeDialog()&quot;
          &gt;&amp;lt;/button&gt;
        &amp;lt;/header&gt;
        &amp;lt;section class=&quot;modal-card-body&quot;&gt;
          &amp;lt;ng-template appDynamicDialogContent&gt;&amp;lt;/ng-template&gt;
        &amp;lt;/section&gt;
      &amp;lt;/div&gt;
    &amp;lt;/div&gt;
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; in&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;* =&gt; out&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;zoomOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;trigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;animation&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;transition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;* =&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;group&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;useAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fadeOut&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; timing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{timing}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@zoom&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;animateChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;{{delayChild}}&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; optional&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRootComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    @&lt;span class=&quot;token function&quot;&gt;ViewChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; contentInsertionPoint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    animationState&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AnimationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Enter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    animationStateChanged&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnimationEvent&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    contentComponentType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; componentRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cfr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ComponentFactoryResolver&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; cdr&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectorRef&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cdr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;markForCheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;destroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;startExitAnimation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;animationState &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AnimationState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Leave&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;loadContentComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cfr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolveComponentFactory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vcr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentInsertionPoint&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;viewContainerRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vcr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;factory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;document:keydown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$event.key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleEscapeKey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Escape&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closeDialog&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Chúng ta dùng &lt;code class=&quot;language-text&quot;&gt;animation&lt;/code&gt; trên phần tử &lt;strong&gt;DOM&lt;/strong&gt; trên cùng, là cái &lt;code class=&quot;language-text&quot;&gt;modal&lt;/code&gt;. Và dùng &lt;code class=&quot;language-text&quot;&gt;zoom&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;modal-card&lt;/code&gt;. Chúng ta cũng dùng đến &lt;code class=&quot;language-text&quot;&gt;dialogConfig&lt;/code&gt; để truyền tham số vào cho animations. Kế đến, chúng ta cài đặt hai sự kiện &lt;code class=&quot;language-text&quot;&gt;@animation.start&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;@animation.done&lt;/code&gt; rồi cho &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt; emit. Giờ ngẫm một chút thì các bạn có thấy: &lt;code class=&quot;language-text&quot;&gt;startExitAnimation()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;dynamicDialogRef.close()&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;animationStateChanged&lt;/code&gt; chạy theo một chuỗi như thế nào chưa? Cuối cùng thì chúng ta dùng &lt;code class=&quot;language-text&quot;&gt;closeDialog()&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;modal-background&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;button.delete&lt;/code&gt; (&lt;code class=&quot;language-text&quot;&gt;close icon&lt;/code&gt;) là xong 🔥.&lt;/p&gt;
&lt;p&gt;Đến đây thì xong khoản 60% rồi 😅. Hoàn tất 40% còn lại với &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; thôi.&lt;/p&gt;
&lt;h3 id=&quot;dynamicdialogservice&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dynamicdialogservice&quot; aria-label=&quot;dynamicdialogservice permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;DynamicDialogService&lt;/h3&gt;
&lt;p&gt;Ngoài &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; là mảng cuối cùng giúp cho người dùng có thể tương tác được với &lt;strong&gt;Dynamic Dialog&lt;/strong&gt;. Mở file &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog.service.ts&lt;/code&gt; rồi quẩy thôi. &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; chỉ cung cấp một hàm duy nhất cho người dùng, đó là &lt;code class=&quot;language-text&quot;&gt;open&amp;lt;TReturnType = any&amp;gt;()&lt;/code&gt;, để người dùng có thể dùng hàm này để thực thi việc &lt;strong&gt;mở&lt;/strong&gt; &lt;strong&gt;Dialog&lt;/strong&gt;.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;9480571483393186000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
  }
}`, `9480571483393186000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hãy import và inject mấy thứ mình cần trước. Sau đó, chúng ta sẽ khai báo &lt;code class=&quot;language-text&quot;&gt;private readonly defaultDialogConfig&lt;/code&gt;. Biến này sẽ giữ một số cấu hình mặc định cho &lt;strong&gt;Dialog&lt;/strong&gt;. Chúng ta đã thiết lập một số cấu hình mặc định bên trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; rồi. Ở đây, chúng ta sẽ thiết lập cấu hình mặc định cho &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;disposeOnNavigation&lt;/code&gt;: Đọc phát hiểu luôn. Chúng ta muốn đóng &lt;strong&gt;Dialog&lt;/strong&gt; khi chúng ta chuyển sang một trang khác. Việc này giúp cho &lt;strong&gt;Dialog&lt;/strong&gt; được dọn dẹp, phòng ngừa tràn bộ nhớ không cần thiết.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;hasBackdrop&lt;/code&gt;: Cái này có thể thiết lập hoặc không. Ở đây thì mình sẽ thiết lập nó thành &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt;. Nếu là &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt;, thì &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; sẽ cho hiển thị một element có class là &lt;code class=&quot;language-text&quot;&gt;cdk-backdrop&lt;/code&gt; cùng với &lt;code class=&quot;language-text&quot;&gt;cdk-overlay&lt;/code&gt; trên cây &lt;strong&gt;DOM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;panelClass&lt;/code&gt;: Class các bạn muốn &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; có, để tinh chỉnh bằng &lt;code class=&quot;language-text&quot;&gt;CSS&lt;/code&gt; nếu muốn.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;scrollStrategy&lt;/code&gt;: Dễ hiểu. Thiết lập tác vụ Scrolling khi &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; được mở. Chúng ta sẽ mặc định nó về &lt;code class=&quot;language-text&quot;&gt;BlockScrollStrategy&lt;/code&gt;. Đọc thêm về &lt;a href=&quot;https://material.angular.io/cdk/overlay/overview#scroll-strategies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;ScrollStrategies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;positionStrategy&lt;/code&gt;: Thiết lập vị trí của &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; khi được mở. Mặc định về &lt;code class=&quot;language-text&quot;&gt;center&lt;/code&gt;. Đọc thêm về &lt;a href=&quot;https://material.angular.io/cdk/overlay/overview#position-strategies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;PositionStrategies&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Kế tiếp, chúng ta khai báo hàm &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; nhận vào một &lt;strong&gt;Generic Type&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;TReturnType&lt;/code&gt;. Chúng ta sẽ cần hàm &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; trả về &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&amp;lt;TReturnType&amp;gt;&lt;/code&gt; để &lt;code class=&quot;language-text&quot;&gt;dynamicDialogRef.afterClosed&lt;/code&gt; sẽ có được type chuẩn xác khi người dùng đăng ký vào nó. &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; sẽ cần 2 tham số: &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; để dùng cho &lt;strong&gt;Dialog Content&lt;/strong&gt; (nhớ &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; không?) và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;. Nếu cấu hình &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; được truyền vào, thì cấu hình truyền vào này sẽ được gộp chung với &lt;code class=&quot;language-text&quot;&gt;defaultDialogConfig&lt;/code&gt;. Sau đó, chúng ta sẽ tạo &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; nên quẩy hàm &lt;code class=&quot;language-text&quot;&gt;createOverlay()&lt;/code&gt; thôi &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;30060161100346794000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
  }

  private createOverlay(config: DynamicDialogConfig): OverlayRef {
    return this.overlay.create(config.overlayConfig);
  }
}`, `30060161100346794000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Cực kỳ đơn giản luôn. Chỉ cần gọi &lt;code class=&quot;language-text&quot;&gt;overlay.create()&lt;/code&gt; và truyền vào &lt;code class=&quot;language-text&quot;&gt;OverlayConfig&lt;/code&gt; từ &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig.overlayConfig&lt;/code&gt; thôi. Giờ có &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; rồi, chúng ta có thể bắt đầu khởi tạo &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;9922229729576438000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
    const dialogRef = new DynamicDialogRef&lt;TReturnType&gt;(overlayRef);
    dialogRef.componentInstance = this.attachDialogContainer(overlayRef, component, dialogRef, mergeConfig);
  }

  private createOverlay(config: DynamicDialogConfig): OverlayRef {
    return this.overlay.create(config.overlayConfig);
  }
}`, `9922229729576438000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dialogRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attachDialogContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Các bạn nhớ &lt;code class=&quot;language-text&quot;&gt;componentInstance&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; có type là &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; chứ? &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; vẫn sẽ được khởi tạo động và đây chính là nới mà &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; từ &lt;strong&gt;Angular CDK&lt;/strong&gt; toả sáng. &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; là một &lt;code class=&quot;language-text&quot;&gt;PortalOutlet&lt;/code&gt; mà bạn có thể dùng để &lt;code class=&quot;language-text&quot;&gt;attach&lt;/code&gt; một &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt; để hiển thị động &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; đó trên màn hình. Thông thường, các bạn có thể dùng tới &lt;a href=&quot;https://angular.io/guide/dynamic-component-loader&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Dynamic Component Loader&lt;/a&gt; để tạo động &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt;. Tuy nhiên, &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; từ &lt;strong&gt;Angular CDK&lt;/strong&gt; cung cấp APIs tốt hơn, dễ sử dụng hơn, dễ dọn dẹp hơn. Giờ thì chiến hàm &lt;code class=&quot;language-text&quot;&gt;attachDialogContainer&lt;/code&gt; thôi.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;20818228615539438000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Overlay, OverlayConfig, OverlayRef } from &apos;@angular/cdk/overlay&apos;;
import { ComponentPortal, PortalInjector } from &apos;@angular/cdk/portal&apos;;
import { Injectable, Injector, Type } from &apos;@angular/core&apos;;
import { DynamicDialogRef } from &apos;./dynamic-dialog-ref&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogConfig } from &apos;./models/dynamic-dialog-config.model&apos;;

@Injectable()
export class DynamicDialogService {

  private readonly defaultDialogConfig: DynamicDialogConfig;

  constructor(private readonly overlay: Overlay, private readonly injector: Injector) {
    this.defaultDialogConfig = new DynamicDialogConfig();
    this.defaultDialogConfig.overlayConfig = new OverlayConfig({
      disposeOnNavigation: true,
      hasBackdrop: true,
      panelClass: &apos;dynamic-dialog-panel&apos;,
      scrollStrategy: overlay.scrollStrategies.block(),
      positionStrategy: overlay.position().global().centerHorizontally().centerVertically()
    });
  }

  open&lt;TReturnType = any&gt;(component: Type&lt;any&gt;, config?: DynamicDialogConfig): DynamicDialogRef&lt;TReturnType&gt; {
    const mergeConfig = {
      ...this.defaultDialogConfig,
      ...config,
      overlayConfig: {
        ...this.defaultDialogConfig.overlayConfig,
        ...(config &amp;&amp; config.overlayConfig ? config.overlayConfig : {})
      }
    };

    const overlayRef = this.createOverlay(mergeConfig);
    const dialogRef = new DynamicDialogRef&lt;TReturnType&gt;(overlayRef);
    dialogRef.componentInstance = this.attachDialogContainer(overlayRef, component, dialogRef, mergeConfig);
    return dialogRef;
  }

  private createOverlay(config: DynamicDialogConfig): OverlayRef {
    return this.overlay.create(config.overlayConfig);
  }

  private attachDialogContainer(overlayRef: OverlayRef, component: Type&lt;any&gt;, dialogRef: DynamicDialogRef, dialogConfig: DynamicDialogConfig): DynamicDialogRootComponent {
    const injector = this.createInjector(dialogRef, dialogConfig);
    const portal = new ComponentPortal(DynamicDialogRootComponent, null, injector);
    const ref = overlayRef.attach(portal);
    ref.instance.contentComponentType = component;
    return ref.instance;
  }

  private createInjector(ref: DynamicDialogRef, config: DynamicDialogConfig): PortalInjector {
    const injectorTokenMap = new WeakMap();
    injectorTokenMap.set(DynamicDialogRef, ref);
    injectorTokenMap.set(DynamicDialogConfig, config);
    return new PortalInjector(this.injector, injectorTokenMap);
  }
}`, `20818228615539438000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ComponentPortal&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/portal&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Type &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRef &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-ref&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogService&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; defaultDialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; overlay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Overlay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; injector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Injector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OverlayConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      disposeOnNavigation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      hasBackdrop&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      panelClass&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dynamic-dialog-panel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      scrollStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollStrategies&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      positionStrategy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerHorizontally&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;centerVertically&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mergeConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      overlayConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defaultDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; overlayRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dialogRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogRef&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;TReturnType&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;componentInstance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attachDialogContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mergeConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; dialogRef&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;overlayConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;attachDialogContainer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;overlayRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; OverlayRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Type&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; injector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; portal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ComponentPortal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; injector&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ref &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; overlayRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;attach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;portal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;contentComponentType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; component&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instance&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ref&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PortalInjector &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; injectorTokenMap &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WeakMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    injectorTokenMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ref&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    injectorTokenMap&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PortalInjector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;injector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; injectorTokenMap&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Điều đầu tiên cần làm là &lt;code class=&quot;language-text&quot;&gt;createInjector()&lt;/code&gt; cho &lt;strong&gt;Dialog&lt;/strong&gt; vì chúng ta cần đem &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; vào &lt;strong&gt;Dependency Injection&lt;/strong&gt; trong instance của &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; instance này sẽ quản lý &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; và &lt;strong&gt;Dialog Content Component&lt;/strong&gt; cho nên nếu &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; có truy xuất đến được &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;, thì trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; và &lt;strong&gt;Dialog Content Component&lt;/strong&gt; cũng sẽ truy xuất được đến cùng &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;config&lt;/code&gt; này. Chúng ta sẽ dùng đến &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; sẽ nhập các &lt;code class=&quot;language-text&quot;&gt;InjectionToken&lt;/code&gt; trong &lt;code class=&quot;language-text&quot;&gt;WeakMap&lt;/code&gt; vào với &lt;code class=&quot;language-text&quot;&gt;parentInjector&lt;/code&gt; (là &lt;code class=&quot;language-text&quot;&gt;Injector&lt;/code&gt; mà chúng ta đã inject bên trong &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; bên trên). Với &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; sẵn sàng rồi, chúng ta có thể bắt đầu khởi tạo tiếp &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;. Giờ thì chỉ cần &lt;code class=&quot;language-text&quot;&gt;attach&lt;/code&gt; thằng &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt; này lên &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; thôi. Gọi hàm &lt;code class=&quot;language-text&quot;&gt;overlayRef.attach()&lt;/code&gt; để làm điều đó. Giá trị được trả về là một con trỏ dẫn đến &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt;. Đây chính là nơi mà mình gán giá trị cho &lt;code class=&quot;language-text&quot;&gt;contentComponentType&lt;/code&gt; bằng tham số &lt;code class=&quot;language-text&quot;&gt;component&lt;/code&gt; được truyền vào cho hàm &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt;. Cuối cùng, chúng ta sẽ trả về giá trị &lt;code class=&quot;language-text&quot;&gt;ref.instance&lt;/code&gt;, chính là con trỏ đến &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; đang được quản lý bởi &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt;. Sau đó, mình sẽ trả về giá trị &lt;code class=&quot;language-text&quot;&gt;dialogRef&lt;/code&gt; cho hàm &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt;. Khi người dùng dùng hàm &lt;code class=&quot;language-text&quot;&gt;open()&lt;/code&gt; để mở một &lt;strong&gt;Dialog&lt;/strong&gt; nào đó, họ sẽ được trả về con trỏ của &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; đó. Với &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt;, họ có thể lắng nghe vào sự kiện &lt;code class=&quot;language-text&quot;&gt;afterClosed&lt;/code&gt; và nhận &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; để thực hiện tiếp logic của ứng dụng.&lt;/p&gt;
&lt;h3 id=&quot;dynamicdialogmodule&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dynamicdialogmodule&quot; aria-label=&quot;dynamicdialogmodule permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;DynamicDialogModule&lt;/h3&gt;
&lt;p&gt;Tất cả các mảnh ghép của &lt;strong&gt;Dynamic Dialog&lt;/strong&gt; đã hoàn tất rồi. Tuy nhiên, chúng ta cần phải quăng tất cả vào &lt;code class=&quot;language-text&quot;&gt;DynamicDialogModule&lt;/code&gt; thì mới dùng được. Mở file &lt;code class=&quot;language-text&quot;&gt;dynamic-dialog.module.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;36302713136608043000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { OverlayModule } from &apos;@angular/cdk/overlay&apos;;
import { CommonModule } from &apos;@angular/common&apos;;
import { NgModule } from &apos;@angular/core&apos;;
import { DynamicDialogContentDirective } from &apos;./dynamic-dialog-content.directive&apos;;
import { DynamicDialogRootComponent } from &apos;./dynamic-dialog-root.component&apos;;
import { DynamicDialogService } from &apos;./dynamic-dialog.service&apos;;


@NgModule({
  declarations: [DynamicDialogContentDirective, DynamicDialogRootComponent],
  imports: [CommonModule, OverlayModule], // &lt;-- import OverlayModule
  entryComponents: [DynamicDialogRootComponent], // &lt;-- thêm DynamicDialogRootComponent vào entryComponents. Chắc chắn rằng DynamicDialogRootComponent cũng được đặt vào declarations nhé.
  providers: [DynamicDialogService] // provide DynamicDialogService
})
export class DynamicDialogModule {
}`, `36302713136608043000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; OverlayModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/cdk/overlay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; CommonModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogContentDirective &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-content.directive&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogRootComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog-root.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;


@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DynamicDialogContentDirective&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;CommonModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OverlayModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- import OverlayModule&lt;/span&gt;
  entryComponents&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DynamicDialogRootComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- thêm DynamicDialogRootComponent vào entryComponents. Chắc chắn rằng DynamicDialogRootComponent cũng được đặt vào declarations nhé.&lt;/span&gt;
  providers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;DynamicDialogService&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// provide DynamicDialogService&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;cách-dùng&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#c%C3%A1ch-d%C3%B9ng&quot; aria-label=&quot;cách dùng permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Cách dùng&lt;/h3&gt;
&lt;p&gt;Trước khi dùng được &lt;strong&gt;Dialog&lt;/strong&gt;, hãy tạo một &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; đơn giản để làm &lt;strong&gt;Dialog Content&lt;/strong&gt;. Chạy lệnh sau&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;23910727003770503000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`# assume you are at the root level of the project (cdk-bulma-dialog)
# mặc định là bạn đang ở root của dự án (cdk-bulma-dialog)
ng generate component test-dialog 
--skipTests 
--inlineTemplate 
--inlineStyle 
--changeDetection=OnPush
--entryComponent`, `23910727003770503000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;# assume you are at the root level of the project (cdk-bulma-dialog)
# mặc định là bạn đang ở root của dự án (cdk-bulma-dialog)
ng generate component test-dialog 
--skipTests 
--inlineTemplate 
--inlineStyle 
--changeDetection=OnPush
--entryComponent&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Chúng ta dùng &lt;strong&gt;CLI&lt;/strong&gt; để khởi tạo &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;inlineTemplate&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;inlineStyle&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;skipTests&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;changeDetection=OnPush&lt;/code&gt;, và &lt;code class=&quot;language-text&quot;&gt;entryComponent&lt;/code&gt;. Component này sẽ cực kì đơn giản nên mình sẽ gom tất cả vào 1 file &lt;code class=&quot;language-text&quot;&gt;*.component.ts&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;entryComponent&lt;/code&gt; sẽ đặt &lt;code class=&quot;language-text&quot;&gt;Component&lt;/code&gt; này vào &lt;code class=&quot;language-text&quot;&gt;entryComponents&lt;/code&gt; trên &lt;code class=&quot;language-text&quot;&gt;AppModule&lt;/code&gt; luôn. Giờ thì mở file &lt;code class=&quot;language-text&quot;&gt;test-dialog.component.ts&lt;/code&gt; và quẩy thôi &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;71857060550310820000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { ChangeDetectionStrategy, Component, OnInit } from &apos;@angular/core&apos;;

@Component({
  selector: &apos;app-test-dialog&apos;,
    template: \`
        &lt;p&gt;test-dialog works!&lt;/p&gt;
        &lt;button class=&amp;quot;button&amp;quot; (click)=&amp;quot;close()&amp;quot;&gt;Close&lt;/button&gt;
    \`,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class TestDialogComponent implements OnInit {

  constructor(
        private readonly dialogConfig: DynamicDialogConfig, 
        private readonly dialogRef: DynamicDialogRef&lt;string&gt;
    ) {}

  ngOnInit() {
  }

  close() {
    this.dialogRef.close(&apos;closed from inside content dialog&apos;);
  }
}`, `71857060550310820000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnInit &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-test-dialog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
        &amp;lt;p&gt;test-dialog works!&amp;lt;/p&gt;
        &amp;lt;button class=&quot;button&quot; (click)=&quot;close()&quot;&gt;Close&amp;lt;/button&gt;
    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  changeDetection&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ChangeDetectionStrategy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OnPush
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TestDialogComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OnInit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogConfig&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogConfig&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dialogRef&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;ngOnInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dialogRef&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;closed from inside content dialog&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Chúng ta chỉ thêm một &lt;code class=&quot;language-text&quot;&gt;button&lt;/code&gt; với &lt;code class=&quot;language-text&quot;&gt;(click)&lt;/code&gt; được gán cho hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt;. Chúng ta cũng inject &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&amp;lt;string&amp;gt;&lt;/code&gt; để kiểm tra xem &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; có hoạt động hay không. Ở trong hàm &lt;code class=&quot;language-text&quot;&gt;close()&lt;/code&gt;, chúng ta gọi &lt;code class=&quot;language-text&quot;&gt;dialogRef.close()&lt;/code&gt; và truyền vào một chuỗi &lt;code class=&quot;language-text&quot;&gt;&amp;#39;closed from inside content dialog&amp;#39;&lt;/code&gt;. Giờ thì mở &lt;code class=&quot;language-text&quot;&gt;app.component.html&lt;/code&gt; và thêm vào dòng code sau&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;75090792841830890000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;button class=&amp;quot;button&amp;quot; (click)=&amp;quot;showOverlay()&amp;quot;&gt;Show Overlay&lt;/button&gt;`, `75090792841830890000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;(click)&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;showOverlay()&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Show Overlay&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;rồi mở file &lt;code class=&quot;language-text&quot;&gt;app.component.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;77814206411744480000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Component } from &apos;@angular/core&apos;;
import { DynamicDialogService } from &apos;./dynamic-dialog/dynamic-dialog.service&apos;;
import { DynamicDialogConfig } from &apos;./dynamic-dialog/models/dynamic-dialog-config.model&apos;;
import { TestDialogComponent } from &apos;./test-dialog/test-dialog.component&apos;;

@Component({
  selector: &apos;app-root&apos;,
  templateUrl: &apos;./app.component.html&apos;,
  styleUrls: [&apos;./app.component.scss&apos;]
})
export class AppComponent {
  constructor(private readonly dynamicDialogService: DynamicDialogService) {
  }

  showOverlay() {
    const config = new DynamicDialogConfig();
    config.header = TestDialogComponent.name;
    const ref = this.dynamicDialogService.open&lt;string&gt;(TestDialogComponent, config);
    ref.afterClosed.subscribe(data =&gt; {
      console.log(&apos;closed with data&apos;, data);
    });
  }
}`, `77814206411744480000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Component &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog/dynamic-dialog.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogConfig &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog/models/dynamic-dialog-config.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; TestDialogComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./test-dialog/test-dialog.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app-root&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  templateUrl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  styleUrls&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./app.component.scss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; dynamicDialogService&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; DynamicDialogService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;showOverlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DynamicDialogConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;header &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ref &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dynamicDialogService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;open&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;afterClosed&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;closed with data&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inject &lt;code class=&quot;language-text&quot;&gt;DynamicDialogService&lt;/code&gt; và triển hàm &lt;code class=&quot;language-text&quot;&gt;showOverlay()&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Khởi tạo một instance &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt; mới, gán chuối &lt;code class=&quot;language-text&quot;&gt;&amp;#39;TestDialogComponent&amp;#39;&lt;/code&gt; vào &lt;code class=&quot;language-text&quot;&gt;header&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Gọi hàm &lt;code class=&quot;language-text&quot;&gt;dynamicDialogService.open()&lt;/code&gt;, với &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;config&lt;/code&gt; là tham số, sau đó gán giá trị được trả về cho biến nội bộ &lt;code class=&quot;language-text&quot;&gt;ref&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Lắng nghe vào sự kiện &lt;code class=&quot;language-text&quot;&gt;ref.afterClosed&lt;/code&gt; và log &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; được truyền ra từ bên trong hàm &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent.close()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Mở file &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt; &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;43250829311229900000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { NgModule } from &apos;@angular/core&apos;;
import { BrowserModule } from &apos;@angular/platform-browser&apos;;
import { BrowserAnimationsModule } from &apos;@angular/platform-browser/animations&apos;; // &lt;-- add this import
import { AppComponent } from &apos;./app.component&apos;;
import { DynamicDialogModule } from &apos;./dynamic-dialog/dynamic-dialog.module&apos;;
import { TestDialogComponent } from &apos;./test-dialog/test-dialog.component&apos;;

@NgModule({
  declarations: [AppComponent, TestDialogComponent],
  imports: [BrowserModule, BrowserAnimationsModule, DynamicDialogModule],
  bootstrap: [AppComponent],
  entryComponents: [TestDialogComponent]
})
export class AppModule {
}`, `43250829311229900000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserAnimationsModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser/animations&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &amp;lt;-- add this import&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AppComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DynamicDialogModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./dynamic-dialog/dynamic-dialog.module&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; TestDialogComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./test-dialog/test-dialog.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BrowserModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; BrowserAnimationsModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DynamicDialogModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bootstrap&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  entryComponents&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;TestDialogComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bảo đảm là bạn có &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; trong &lt;code class=&quot;language-text&quot;&gt;entryComponents&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogModule&lt;/code&gt; trong &lt;code class=&quot;language-text&quot;&gt;imports&lt;/code&gt;. Ok, giờ thì mọi thứ sẵn sàng rồi. Khoảnh khắc sự thật là đây! Chạy ứng dụng thôi&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;69007265100445520000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng serve -o`, `69007265100445520000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;ng serve -o&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Bạn sẽ thấy được cái nút như sau trên màn hình&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b83c04dd99f2bc088bb714564a38dc44/fca82/show-overlay-btn.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 92.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAATCAYAAACQjC21AAAACXBIWXMAAAsSAAALEgHS3X78AAAAVklEQVQ4y+2UMQrAUAhDvf9VnR1UNKUFW/hb6x86GIiIwzMuEjNDRODuMLOWVRWEjcpM0Fl2OSIeYG2o/k2q0gVch1/OHOAAB/gfYNc3sJNu1daE9Q8PUTvnj4pducIAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;show overlay btn&quot;
        title=&quot;show overlay btn&quot;
        src=&quot;/static/b83c04dd99f2bc088bb714564a38dc44/1bed9/show-overlay-btn.png&quot;
        srcset=&quot;/static/b83c04dd99f2bc088bb714564a38dc44/7b64c/show-overlay-btn.png 160w,
/static/b83c04dd99f2bc088bb714564a38dc44/4e610/show-overlay-btn.png 320w,
/static/b83c04dd99f2bc088bb714564a38dc44/1bed9/show-overlay-btn.png 640w,
/static/b83c04dd99f2bc088bb714564a38dc44/7d769/show-overlay-btn.png 960w,
/static/b83c04dd99f2bc088bb714564a38dc44/f3baa/show-overlay-btn.png 1280w,
/static/b83c04dd99f2bc088bb714564a38dc44/fca82/show-overlay-btn.png 2058w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Lonely Show Overlay button&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Click vào &lt;code class=&quot;language-text&quot;&gt;Show Overlay&lt;/code&gt; sẽ mở &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; với backdrop màu xám đậm.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/87966e6ae7e47878673d6d0a91b30b4d/9e121/overlay.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 91.875%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsSAAALEgHS3X78AAAA+ElEQVQ4y82TSwqDMBCGPYOKuvCtV3DhDdwJuhJvogjq/cSNB9GNulD+khSp6QNsLaWBj0kC8zF5DGeaJgzDAImWZdG4zT+Bu0q2DXM3PyXcqjsvZYS3I39ReBbu/iFc132L+4KYCjVNgyiKD/A8/xRBEGjO3sFtZlVV4fs+iqJAlmXI85xC1nVdM1RVRWNZlvA8j+batn0TOo4DWZaRJAmmaULf95RhGDCOI16NZVkQRREkSaIORkg20zTFuq6Y5xlHRxzHj0JSrqIoCMMQbduiaRp0XXeIIAhoLnPkfduRNtR1nV72Efa5X/uHL7/N3wh/03p/K7wA7ShWilPFNB4AAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;overlay&quot;
        title=&quot;overlay&quot;
        src=&quot;/static/87966e6ae7e47878673d6d0a91b30b4d/1bed9/overlay.png&quot;
        srcset=&quot;/static/87966e6ae7e47878673d6d0a91b30b4d/7b64c/overlay.png 160w,
/static/87966e6ae7e47878673d6d0a91b30b4d/4e610/overlay.png 320w,
/static/87966e6ae7e47878673d6d0a91b30b4d/1bed9/overlay.png 640w,
/static/87966e6ae7e47878673d6d0a91b30b4d/7d769/overlay.png 960w,
/static/87966e6ae7e47878673d6d0a91b30b4d/f3baa/overlay.png 1280w,
/static/87966e6ae7e47878673d6d0a91b30b4d/9e121/overlay.png 2062w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Tada!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Mở &lt;strong&gt;Console&lt;/strong&gt; lên, rồi click vào &lt;code class=&quot;language-text&quot;&gt;Close&lt;/code&gt;, các bạn sẽ thấy &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;42609419514594920000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`closed with data closed from inside content dialog`, `42609419514594920000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;closed with data closed from inside content dialog&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;được log ra &lt;strong&gt;Console&lt;/strong&gt;. 👍&lt;/p&gt;
&lt;h3 id=&quot;recap&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#recap&quot; aria-label=&quot;recap permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Recap&lt;/h3&gt;
&lt;p&gt;Để điểm lại, mình có vẽ một cái diagram gớm ghiếc này&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/27c6a7876f5916d8bb7f7fe73a90d1f0/94b18/diagram.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 91.25000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAAsSAAALEgHS3X78AAABZ0lEQVQ4y52U2Y6DMAxF+f/vpA8FCl3YCrQZnUgHBTRdZiy5IbF9fWM7zZZlCc/nM4zjGPq+j6vK/n6/h8fjEfBT53ne7FPN+BmGIdxut6AAgmj7EyDBbdvGQBRmrJz/i2HTNKEoihiYOrO+CnwL2HVduF6vkdkn569rKOjpdAowZr+/5h4Qu7oBNJudxsH6UUtXkkzTtALYSM7SOmd8cEhgVVXR6XK5RHAcWbG7h8D5fF4bqU0ymRsc6rqOYAQQbHZWy4Kd0hyPx5icBI4aOJlzlgrU94IzoCRGAWXvzOqTSRWQw+EQ8jyPY2RzZABLa8aZzFMyK0MaggNX4rqogNQWu03g7DchCT4bQLLxnQogZGYF3Pfu6MgWnNjlFJCmlGUZg3C0gxbdueNbEL+1rTVEvFb69LT5klTrvh/uyNDCG7gXbgDrr54eRv/7GAeGm1mj+P4DOcAy+fiWLa4Di9LxV+/5HeAPLreC+qaycBEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;diagram&quot;
        title=&quot;diagram&quot;
        src=&quot;/static/27c6a7876f5916d8bb7f7fe73a90d1f0/1bed9/diagram.png&quot;
        srcset=&quot;/static/27c6a7876f5916d8bb7f7fe73a90d1f0/7b64c/diagram.png 160w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/4e610/diagram.png 320w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/1bed9/diagram.png 640w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/7d769/diagram.png 960w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/f3baa/diagram.png 1280w,
/static/27c6a7876f5916d8bb7f7fe73a90d1f0/94b18/diagram.png 1676w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;…😢&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ở một góc nhìn toàn diện, sau đây là mọi thứ diễn ra khi bạn gọi hàm &lt;code class=&quot;language-text&quot;&gt;dynamicDialogService.open()&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; instance sẽ được khởi tạo để quản lý &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;OverlayRef&lt;/code&gt; xử lý &lt;code class=&quot;language-text&quot;&gt;PortalOutlet&lt;/code&gt; và trên &lt;code class=&quot;language-text&quot;&gt;PortalOutlet&lt;/code&gt;, chúng ta hiển thị &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRootComponent&lt;/code&gt; thông qua &lt;code class=&quot;language-text&quot;&gt;ComponentPortal&lt;/code&gt;. Sau đó, chúng ta có thiết lập &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; để inject những instances hiện tại của &lt;code class=&quot;language-text&quot;&gt;DynamicDialogRef&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;DynamicDialogConfig&lt;/code&gt;. 2 thằng này sau khi được &lt;code class=&quot;language-text&quot;&gt;PortalInjector&lt;/code&gt; inject thì sẽ có thể được truy xuất tới trong &lt;strong&gt;Dialog Content Component&lt;/strong&gt; (là &lt;code class=&quot;language-text&quot;&gt;TestDialogComponent&lt;/code&gt; trong ví dụ). Tất cả mọi thứ chỉ có vậy thôi. &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; là hai công cụ cực kỳ ngon mà &lt;strong&gt;Angular CDK&lt;/strong&gt; cung cấp cho các bạn tạo điều kiện cho developers có thể xây dựng những components chất lượng như &lt;strong&gt;Dynamic Dialog&lt;/strong&gt;. Với kiến thức tương tự, các bạn có thể áp dụng &lt;code class=&quot;language-text&quot;&gt;Overlay&lt;/code&gt; và &lt;code class=&quot;language-text&quot;&gt;Portal&lt;/code&gt; để xây dựng những components tương tự khác như: &lt;strong&gt;Tooltip&lt;/strong&gt;, &lt;strong&gt;Drawer&lt;/strong&gt;, &lt;strong&gt;Toast&lt;/strong&gt; etc… 💪&lt;/p&gt;
&lt;p&gt;Kết bài, mình hy vọng là đã chia sẻ được cái gì đó và các bạn đã học thêm được cái gì đó qua bài blog dài ngoằng này 🚀. Have fun và good luck nhé. Hẹn gặp lại các bạn trong bài blog kế tiếp 👋&lt;/p&gt;
&lt;h3 id=&quot;reference&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#reference&quot; aria-label=&quot;reference permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reference&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.thoughtram.io/angular/2017/11/20/custom-overlays-with-angulars-cdk.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Custom Overlays With Angular CDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://netbasal.com/creating-powerful-components-with-angular-cdk-2cef53d81cea&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Creating Powerful Components With Angular CDK&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Customize UI Library in Angular]]></title><description><![CDATA[Happy New Year everyone 🎇! I hope everyone will have a prosperous new year ahead of you all. As for me, I want to kick off 2020 with a new…]]></description><link>https://nartc.netlify.com/blogs/customize-ui-library-angular/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/customize-ui-library-angular/</guid><pubDate>Wed, 01 Jan 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Happy New Year everyone 🎇! I hope everyone will have a prosperous new year ahead of you all. As for me, I want to kick off 2020 with a new blog post, to stay &lt;strong&gt;productive&lt;/strong&gt; you know 💪. So what are we going to do today? We are going to look at how we can customize 3rd party library (if applicable 🤞) in an &lt;strong&gt;Angular&lt;/strong&gt; application.&lt;/p&gt;
&lt;h3 id=&quot;the-problem&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-problem&quot; aria-label=&quot;the problem permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Problem&lt;/h3&gt;
&lt;p&gt;As Web Technologies improve, there are a lot of 3rd-party UI libraries out there that we, &lt;strong&gt;Web Developers&lt;/strong&gt;, can utilize without reinventing the wheels from scratch (Sometimes, building from scratch makes sense for your case/company/team 😊). However, these 3rd-party libraries are most of the times, &lt;strong&gt;opinionated&lt;/strong&gt;, and a &lt;em&gt;particular&lt;/em&gt; one library will never be able to fulfill &lt;em&gt;all&lt;/em&gt; of your project’s needs. That’s why “sometimes, building from scratch makes sense”.&lt;/p&gt;
&lt;p&gt;Inexperienced developers or teams will tend to pull in many different libraries to have coverage of their usages. For example, they might pull in &lt;code class=&quot;language-text&quot;&gt;library-A&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;DataTable&lt;/code&gt; usage but &lt;code class=&quot;language-text&quot;&gt;library-A&lt;/code&gt;’s &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; does not cut it so they pull in &lt;code class=&quot;language-text&quot;&gt;library-B&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;library-B&lt;/code&gt;’s &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt;. Although, this will make your team get a feature out quickly enough and make customers happy but overall, this is a bad practice. Not only that you have increased the application’s bundle-size with multiple libraries but you also increase the tech-debt with &lt;strong&gt;two&lt;/strong&gt; external libraries to keep track off and keep up-to-date.&lt;/p&gt;
&lt;p&gt;Now, I am talking about &lt;strong&gt;Open Source Software (OSS)&lt;/strong&gt; that are free to use provided to developers by other developers. Usually, &lt;strong&gt;paid counterpart&lt;/strong&gt; provides supports that might be able to help you with your &lt;em&gt;missing feature&lt;/em&gt;. However, that is not always the case with &lt;strong&gt;OSS&lt;/strong&gt;. Normally, you would probably follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Google a solution regarding the usage you want with the library you use. Sometimes, this will lead you to the library’s &lt;strong&gt;Github Issues&lt;/strong&gt; where it’s most likely that someone else has already had the same issue as yours&lt;/li&gt;
&lt;li&gt;File an issue/feature request on the library’s &lt;strong&gt;Github&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Wait for something to happen to your issue/feature request.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Some people will just stop there, and wait ⏱. But, there is a couple of additional steps that you might want to look at:&lt;/p&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Look at the library’s source code&lt;/li&gt;
&lt;li&gt;Customize it&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Most UI libraries are just &lt;strong&gt;JavaScript&lt;/strong&gt; so most likely, you’ll be able to customize it no problem. The hard part is to conform with whatever framework you’re using for your project. In this blog, I will be going over a use-case with &lt;strong&gt;PrimeNG&lt;/strong&gt;’s &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt;. &lt;/p&gt;
&lt;h3 id=&quot;use-case&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#use-case&quot; aria-label=&quot;use case permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Use-case&lt;/h3&gt;
&lt;p&gt;What is &lt;strong&gt;PrimeNG&lt;/strong&gt;? &lt;a href=&quot;https://www.primefaces.org/primeng/#/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;PrimeNG&lt;/a&gt; is a 3rd-party UI Component Suite for &lt;strong&gt;Angular&lt;/strong&gt;. It is pretty complete in my opinion. But of course, nothing is perfect. One particular case that we run into for our project is their &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; is not &lt;em&gt;mobile-friendly&lt;/em&gt;. In other words, the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; does not play well with mobile viewports as it does not support &lt;code class=&quot;language-text&quot;&gt;click triggering&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/9XC5lzp.gif&quot; alt=&quot;problem&quot;&gt;
&lt;em&gt;&lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; is not mobile friendly&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;What can you do? Well, &lt;strong&gt;NgBootstrap&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; does have &lt;code class=&quot;language-text&quot;&gt;click triggering&lt;/code&gt; which you can always pull in your project and use &lt;strong&gt;NgBootstrap&lt;/strong&gt; just for their &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt;. Or, you can go to &lt;a href=&quot;https://github.com/primefaces/primeng&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;PrimeNG Github&lt;/a&gt; and submit a feature request for &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; to support &lt;code class=&quot;language-text&quot;&gt;click triggering&lt;/code&gt;, which I think that’s the way it should be.&lt;/p&gt;
&lt;h3 id=&quot;while-you-wait&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#while-you-wait&quot; aria-label=&quot;while you wait permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;While you wait&lt;/h3&gt;
&lt;p&gt;Your feature request probably takes a while for it to be looked at, let alone worked on. In the mean time, we can utilize &lt;strong&gt;step 4&lt;/strong&gt; and &lt;strong&gt;step 5&lt;/strong&gt; above.&lt;/p&gt;
&lt;p&gt;Let’s get started with reading &lt;strong&gt;PrimeNG&lt;/strong&gt; source code on how they implement their &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; at &lt;a href=&quot;https://github.com/primefaces/primeng/blob/master/src/app/components/tooltip/tooltip.ts&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;tooltip.ts&lt;/a&gt;. Let’s walk over the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;75109815307926400000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`@Directive({
    selector: &apos;[pTooltip]&apos;
})
export class Tooltip implements AfterViewInit, OnDestroy {
  // ...
}`, `75109815307926400000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[pTooltip]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Tooltip&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can tell right away that &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt;. It implements &lt;code class=&quot;language-text&quot;&gt;AfterViewInit&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;OnDestroy&lt;/code&gt;. Let’s see what &lt;strong&gt;PrimeNG&lt;/strong&gt; does in &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit&lt;/code&gt; and let me highlight the important pieces for you&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;91085402901074250000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ngAfterViewInit() {
    this.zone.runOutsideAngular(() =&gt; {
        if (this.tooltipEvent === &apos;hover&apos;) {
            this.mouseEnterListener = this.onMouseEnter.bind(this);
            this.mouseLeaveListener = this.onMouseLeave.bind(this);
            this.clickListener = this.onClick.bind(this);
            this.el.nativeElement.addEventListener(&apos;mouseenter&apos;, this.mouseEnterListener);
            this.el.nativeElement.addEventListener(&apos;mouseleave&apos;, this.mouseLeaveListener);
            this.el.nativeElement.addEventListener(&apos;click&apos;, this.clickListener);
        }
        else if (this.tooltipEvent === &apos;focus&apos;) {
            this.focusListener = this.onFocus.bind(this);
            this.blurListener = this.onBlur.bind(this);
            this.el.nativeElement.addEventListener(&apos;focus&apos;, this.focusListener);
            this.el.nativeElement.addEventListener(&apos;blur&apos;, this.blurListener);
        }
    });
}`, `91085402901074250000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;runOutsideAngular&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltipEvent &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;hover&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mouseEnterListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onMouseEnter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mouseLeaveListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onMouseLeave&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mouseenter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mouseEnterListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mouseleave&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mouseLeaveListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;        &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltipEvent &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;focus&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;focusListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onFocus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blurListener &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onBlur&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;focus&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;focusListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;blur&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blurListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s see:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;They run some code outside of &lt;strong&gt;Angular Change Detection&lt;/strong&gt; with &lt;code class=&quot;language-text&quot;&gt;runOutsideAngular()&lt;/code&gt; provided by &lt;code class=&quot;language-text&quot;&gt;NgZone&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;NgZone&lt;/code&gt; is another complex topic that you can read more about at &lt;a href=&quot;https://indepth.dev/do-you-still-think-that-ngzone-zone-js-is-required-for-change-detection-in-angular/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Do You Still Think That Ngzone Zone Js Is Required For Change Detection In Angular?&lt;/a&gt; and/or &lt;a href=&quot;https://medium.com/angular-in-depth/boosting-performance-of-angular-applications-with-manual-change-detection-42cb396110fb&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Boosting Performance Of Angular Applications With Manual Change Detection&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If the &lt;code class=&quot;language-text&quot;&gt;tooltipEvent&lt;/code&gt; is &lt;code class=&quot;language-text&quot;&gt;hover&lt;/code&gt;, then they bind some &lt;code class=&quot;language-text&quot;&gt;mouseEnter&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;mouseLeave&lt;/code&gt; events which makes total sense.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, let’s look at &lt;code class=&quot;language-text&quot;&gt;onMouseEnter&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;onMouseLeave&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;onClick&lt;/code&gt; that &lt;strong&gt;PrimeNG&lt;/strong&gt; uses to bind to the events.  &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;79020625776857200000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`onMouseEnter(e: Event) {
    if (!this.container &amp;&amp; !this.showTimeout) {
        this.activate();
    }
}

onMouseLeave(e: Event) {
    this.deactivate();
}

onClick(e: Event) {
    this.deactivate();
}`, `79020625776857200000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;onMouseEnter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;container &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showTimeout&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;onMouseLeave&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;this.container&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;this.showTimeout&lt;/code&gt; are just extra information. What we need to focus on is: &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; methods. We can kind of tell that &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt; will show the &lt;code class=&quot;language-text&quot;&gt;tooltip&lt;/code&gt; and vice versa for &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt;. Let’s take a look&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;8701314742973820000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`activate() {
    this.active = true;
    this.clearHideTimeout();

    if (this.showDelay)
        this.showTimeout = setTimeout(() =&gt; { this.show() }, this.showDelay);
    else
        this.show();

    if (this.life) {
        let duration = this.showDelay ? this.life + this.showDelay : this.life;
        this.hideTimeout = setTimeout(() =&gt; { this.hide() }, duration);
    }
}

deactivate() {
    this.active = false;
    this.clearShowTimeout();

    if (this.hideDelay) {
        this.clearHideTimeout();
        this.hideTimeout = setTimeout(() =&gt; { this.hide() }, this.hideDelay);
    }
    else {
        this.hide();
    }
}`, `8701314742973820000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clearHideTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showDelay&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showTimeout &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showDelay&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;show&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;life&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; duration &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showDelay &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;life &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;showDelay &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;life&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hideTimeout &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; duration&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clearShowTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hideDelay&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clearHideTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hideTimeout &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hideDelay&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;hide&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’s clear to see that upon calling &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt;, &lt;strong&gt;PrimeNG&lt;/strong&gt; sets &lt;code class=&quot;language-text&quot;&gt;active&lt;/code&gt; flag to &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; and have extra logic around its properties to determine how to display the &lt;code class=&quot;language-text&quot;&gt;tooltip&lt;/code&gt;, vice versa with &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt;. Up to now, we probably have enough background of how &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; works in &lt;strong&gt;PrimeNG&lt;/strong&gt;. Now on to customizing it.&lt;/p&gt;
&lt;h3 id=&quot;the-solution&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-solution&quot; aria-label=&quot;the solution permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Solution&lt;/h3&gt;
&lt;p&gt;The first step is to run through what we need to do: (rationale)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We still want to have the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; behave with the default &lt;code class=&quot;language-text&quot;&gt;hover trigger&lt;/code&gt; so we’ll leave: &lt;code class=&quot;language-text&quot;&gt;tooltipEvent&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;onMouseEnter&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;onMouseLeave&lt;/code&gt; as is.&lt;/li&gt;
&lt;li&gt;We need to attach an event that we can use on mobile viewports.&lt;/li&gt;
&lt;li&gt;We will need to leverage &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; methods for step 2 to work.&lt;/li&gt;
&lt;li&gt;We will also need to handle some kind of &lt;code class=&quot;language-text&quot;&gt;click outside&lt;/code&gt; so we can &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; on mobile viewports.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s start, shall we?&lt;/p&gt;
&lt;p&gt;First step is to just initialize yourself an &lt;strong&gt;Angular&lt;/strong&gt; application with &lt;strong&gt;PrimeNG&lt;/strong&gt; setup. For the purpose of this demo, let’s use &lt;code class=&quot;language-text&quot;&gt;ButtonModule&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; from &lt;strong&gt;PrimeNG&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;After all that, let’s open up &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;91753966933120970000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { NgModule } from &apos;@angular/core&apos;;
import { BrowserModule } from &apos;@angular/platform-browser&apos;;
import { ButtonModule } from &apos;primeng/button&apos;;
import { TooltipModule } from &apos;primeng/tooltip&apos;;

import { AppComponent } from &apos;./app.component&apos;;

@NgModule({
  imports: [BrowserModule, ButtonModule, TooltipModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule {}`, `91753966933120970000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NgModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BrowserModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/platform-browser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ButtonModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;primeng/button&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; TooltipModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;primeng/tooltip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AppComponent &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.component&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;NgModule&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;BrowserModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ButtonModule&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; TooltipModule&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;  declarations&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bootstrap&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;AppComponent&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In &lt;code class=&quot;language-text&quot;&gt;app.component.html&lt;/code&gt;, let’s remove everything and add the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;88500881906027510000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;p-button label=&amp;quot;PrimeNG Button&amp;quot; pTooltip=&amp;quot;I am a not so mobile friendly tooltip&amp;quot;&gt;&lt;/p-button&gt;`, `88500881906027510000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p-button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;PrimeNG Button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;pTooltip&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;I am a not so mobile friendly tooltip&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p-button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run the application with &lt;code class=&quot;language-text&quot;&gt;ng serve&lt;/code&gt;, you should see a &lt;code class=&quot;language-text&quot;&gt;PrimeNG Button&lt;/code&gt; on the screen, and the &lt;code class=&quot;language-text&quot;&gt;tooltip&lt;/code&gt; when you hover over the button as well (just like the demo up there). Now, let’s create a &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt;. I am going to create it manually, although you can use &lt;code class=&quot;language-text&quot;&gt;Angular CLI&lt;/code&gt; to generate a &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt; with the following command.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;75430917353570480000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`ng g directive tooltip-click --skipTests`, `75430917353570480000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;ng g directive tooltip-click --skipTests&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open up &lt;code class=&quot;language-text&quot;&gt;tooltip-click.directive.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;85959470177263220000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Directive } from &apos;@angular/core&apos;;

@Directive({
  selector: &apos;[pTooltip][clickTrigger]&apos; // change the selector
})
export class TooltipClickDirective {}`, `85959470177263220000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[pTooltip][clickTrigger]&apos;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// change the selector&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TooltipClickDirective&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First thing to do is to change the &lt;code class=&quot;language-text&quot;&gt;selector&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;[pTooltip][clickTrigger]&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;[pTooltip]&lt;/code&gt; part lets us &lt;em&gt;patch&lt;/em&gt; &lt;code class=&quot;language-text&quot;&gt;TooltipClickDirective&lt;/code&gt; on top of &lt;strong&gt;PrimeNG&lt;/strong&gt;’s one. &lt;code class=&quot;language-text&quot;&gt;[clickTrigger]&lt;/code&gt; is arbitrary but you need to make sure you pick an &lt;strong&gt;attribute name&lt;/strong&gt; that is unique enough. So, with &lt;code class=&quot;language-text&quot;&gt;[pTooltip][clickTrigger]&lt;/code&gt;, our &lt;code class=&quot;language-text&quot;&gt;TooltipClickDirective&lt;/code&gt; will be initialized with:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;63488369795172650000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;p-button label=&amp;quot;PrimeNG Button&amp;quot; pTooltip=&amp;quot;...&amp;quot; clickTrigger&gt;&lt;/p-button&gt;`, `63488369795172650000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p-button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;PrimeNG Button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;pTooltip&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;clickTrigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p-button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Remember what &lt;strong&gt;PrimeNG&lt;/strong&gt;’s &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; implements? &lt;code class=&quot;language-text&quot;&gt;AfterViewInit&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;OnDestroy&lt;/code&gt; right? And we’re going to do the same for &lt;code class=&quot;language-text&quot;&gt;TooltipClickDirective&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;34066041497069265000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Directive, AfterViewInit, OnDestroy } from &apos;@angular/core&apos;;

@Directive({
  selector: &apos;[pTooltip][clickTrigger]&apos;
})
export class TooltipClickDirective implements AfterViewInit, OnDestroy {
  
  ngAfterViewInit() {
    
  }
  
  ngOnDestroy() {
    
  }
}`, `34066041497069265000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[pTooltip][clickTrigger]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TooltipClickDirective&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;We didn’t really go over &lt;strong&gt;PrimeNG&lt;/strong&gt;’s &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy&lt;/code&gt; but essentially, they unbind the events that they bind in &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We’re going to inject a couple of things in our &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;constructor&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;74324942327395610000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Directive, AfterViewInit, OnDestroy, NgZone } from &apos;@angular/core&apos;;
import { Tooltip } from &apos;primeng/tooltip&apos;;

@Directive({
  selector: &apos;[pTooltip][clickTrigger]&apos;
})
export class TooltipClickDirective implements AfterViewInit, OnDestroy {
 
  constructor(private readonly tooltip: Tooltip, private readonly ngZone: NgZone) {}
  
  ngAfterViewInit() {
    
  }
  
  ngOnDestroy() {
    
  }
}`, `74324942327395610000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NgZone &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Tooltip &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;primeng/tooltip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[pTooltip][clickTrigger]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TooltipClickDirective&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
 
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; tooltip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tooltip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; ngZone&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; NgZone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;  
  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, remember &lt;strong&gt;PrimeNG&lt;/strong&gt; uses &lt;code class=&quot;language-text&quot;&gt;NgZone&lt;/code&gt; to run some event bindings outside of &lt;code class=&quot;language-text&quot;&gt;Angular&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;runOutsideAngular&lt;/code&gt;. We are going to do the same here. And &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; will give us the instance of the &lt;strong&gt;PrimeNG&lt;/strong&gt;’s &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; in our &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In your &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt;, you can use &lt;strong&gt;Dependency Injection (DI)&lt;/strong&gt; to inject a couple of very useful things like &lt;code class=&quot;language-text&quot;&gt;ElementRef&lt;/code&gt; (the actual DOM element), &lt;code class=&quot;language-text&quot;&gt;NgControl&lt;/code&gt; (the &lt;code class=&quot;language-text&quot;&gt;FormControl&lt;/code&gt; that the &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt; is used on) etc… and also the &lt;strong&gt;Component Instance&lt;/strong&gt; (like &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; instance that we’re utilizing here)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We are going to take care of a couple of low-hanging fruits next, namely: &lt;code class=&quot;language-text&quot;&gt;toggleTooltip()&lt;/code&gt; method, &lt;code class=&quot;language-text&quot;&gt;click-outside&lt;/code&gt; event and a small setup in &lt;code class=&quot;language-text&quot;&gt;ngAfterViewInit()&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;24303199687652045000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Directive, AfterViewInit, OnDestroy, NgZone } from &apos;@angular/core&apos;;
import { Tooltip } from &apos;primeng/tooltip&apos;;

@Directive({
  selector: &apos;[pTooltip][clickTrigger]&apos;
})
export class TooltipClickDirective implements AfterViewInit, OnDestroy {
 
  constructor(private readonly tooltip: Tooltip, private readonly ngZone: NgZone) {}
  
  ngAfterViewInit() {
    this.ngZone.runOutsideAngular(() =&gt; {
      if (this.tooltip.clickListener) {
        this.tooltip.el.nativeElement.removeEventListener(&apos;click&apos;, this.tooltip.clickListener);
      }
    });
  }
  
  ngOnDestroy() {
    
  }
  
  @HostListener(&apos;document:click&apos;, [&apos;\$event.target&apos;])
  onClickOutside(target: Node) {
    if (!this.tooltip.el.nativeElement.contains(target) &amp;&amp; this.tooltip.active) {
      this.tooltip.deactivate();
    }
  }
  
  private toggleTooltip() {
    if (this.tooltip.active) {
      this.tooltip.deactivate();
    } else {
      this.tooltip.activate();
    }
  }
}`, `24303199687652045000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NgZone &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Tooltip &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;primeng/tooltip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[pTooltip][clickTrigger]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TooltipClickDirective&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
 
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; tooltip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tooltip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; ngZone&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; NgZone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ngZone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;runOutsideAngular&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;document:click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$event.target&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token function&quot;&gt;onClickOutside&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;target&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Node&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;  
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toggleTooltip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s go through each block, &lt;strong&gt;from bottom to top&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;toggleTooltip()&lt;/code&gt;: This is very straight-forward. We check if the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; instance is &lt;code class=&quot;language-text&quot;&gt;active&lt;/code&gt;, if yes, we &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; it, else, we &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt; it.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;HostListener()&lt;/code&gt;: This is our &lt;code class=&quot;language-text&quot;&gt;click-outside&lt;/code&gt; piece. It listens to click on the &lt;code class=&quot;language-text&quot;&gt;Document&lt;/code&gt; and will check if the &lt;code class=&quot;language-text&quot;&gt;EventTarget&lt;/code&gt; is the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt;’s &lt;code class=&quot;language-text&quot;&gt;nativeElement&lt;/code&gt; which is whatever element we use our &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt; on, if yes and if the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; is &lt;code class=&quot;language-text&quot;&gt;active&lt;/code&gt;, we &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; it, else, we do nothing. This &lt;code class=&quot;language-text&quot;&gt;HostListener&lt;/code&gt; will get unbound when the &lt;code class=&quot;language-text&quot;&gt;Directive&lt;/code&gt; is destroyed.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;runOutsideAngular()&lt;/code&gt;: You might be wondering why do we need to check for the instance’s &lt;code class=&quot;language-text&quot;&gt;clickListener&lt;/code&gt; and remove it. Remember what &lt;code class=&quot;language-text&quot;&gt;onClick&lt;/code&gt; does in &lt;strong&gt;PrimeNG&lt;/strong&gt;’s &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt;? It calls &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; but we really need a &lt;code class=&quot;language-text&quot;&gt;click event&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;toggleTooltip()&lt;/code&gt; instead of just &lt;code class=&quot;language-text&quot;&gt;deactivate()&lt;/code&gt; it. That’s why we’re removing the &lt;code class=&quot;language-text&quot;&gt;clickListener&lt;/code&gt; and attaching a new event of our own. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, you might be jumping to conclusion that “We’re going to use &lt;code class=&quot;language-text&quot;&gt;HostListener&lt;/code&gt; to listen to the &lt;code class=&quot;language-text&quot;&gt;click&lt;/code&gt; event then handle it”. Well, you might be right but you’ll soon find out that it’s not going to work. A &lt;code class=&quot;language-text&quot;&gt;click event&lt;/code&gt; will also trigger &lt;code class=&quot;language-text&quot;&gt;mouseenter event&lt;/code&gt; which in our case, we still need the &lt;code class=&quot;language-text&quot;&gt;hover effect&lt;/code&gt; on large viewports so the &lt;code class=&quot;language-text&quot;&gt;mouseenter event&lt;/code&gt; is still there in the original &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; instance. You should be curious to try but to save time, I’m going to let you know what happen: It will take two &lt;code class=&quot;language-text&quot;&gt;clicks&lt;/code&gt; to display the tooltip instead of one. Why? Because the original &lt;code class=&quot;language-text&quot;&gt;Tooltip.onMouseEnter()&lt;/code&gt; will call &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt; and remember what &lt;code class=&quot;language-text&quot;&gt;activate()&lt;/code&gt; does? It sets &lt;code class=&quot;language-text&quot;&gt;Tooltip.active&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt; which will conflict with out &lt;code class=&quot;language-text&quot;&gt;toggleTooltip()&lt;/code&gt; method which we check for &lt;code class=&quot;language-text&quot;&gt;Tooltip.active&lt;/code&gt; to display the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt;. Right? So we need to find another way.&lt;/p&gt;
&lt;p&gt;One thing that comes to my mind, for my use-case, is the following question: “What really is a click on mobile devices?” And you know, a &lt;code class=&quot;language-text&quot;&gt;click&lt;/code&gt; on mobile devices is actually a &lt;code class=&quot;language-text&quot;&gt;press&lt;/code&gt;, or more accurately, a &lt;code class=&quot;language-text&quot;&gt;tap&lt;/code&gt;. I bet most of you have heard of &lt;code class=&quot;language-text&quot;&gt;hammerjs&lt;/code&gt; if you have ever used &lt;strong&gt;Angular Material&lt;/strong&gt;. &lt;strong&gt;HammerJS&lt;/strong&gt; is a &lt;strong&gt;JavaScript&lt;/strong&gt; library that adds &lt;em&gt;Touch gestures to your webapp&lt;/em&gt; and that sounds exactly like what we need, a &lt;code class=&quot;language-text&quot;&gt;tap&lt;/code&gt; gesture. Let’s go ahead and install &lt;code class=&quot;language-text&quot;&gt;hammerjs&lt;/code&gt; if you haven’t already.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;73108592923236810000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`yarn add hammerjs
yarn add -D @types/hammerjs`, `73108592923236810000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; hammerjs
&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; -D @types/hammerjs&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;I know I lied about pulling libraries. At the time, our project has &lt;code class=&quot;language-text&quot;&gt;hammerjs&lt;/code&gt; installed as well as most of our other web projects. &lt;code class=&quot;language-text&quot;&gt;hammerjs&lt;/code&gt; is always there. So, let’s move on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;HammerJS&lt;/strong&gt; has an event that we’re interested in: &lt;code class=&quot;language-text&quot;&gt;singletap&lt;/code&gt; so let’s start wiring it up&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;30609090288027718000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import &apos;hammerjs&apos;;
import { Directive, AfterViewInit, OnDestroy, NgZone } from &apos;@angular/core&apos;;
import { Tooltip } from &apos;primeng/tooltip&apos;;

@Directive({
  selector: &apos;[pTooltip][clickTrigger]&apos;
})
export class TooltipClickDirective implements AfterViewInit, OnDestroy {
  
  private hammerManager: HammerManager;
 
  constructor(private readonly tooltip: Tooltip, private readonly ngZone: NgZone) {}
  
  ngAfterViewInit() {
    this.ngZone.runOutsideAngular(() =&gt; {
      if (this.tooltip.clickListener) {
        this.tooltip.el.nativeElement.removeEventListener(&apos;click&apos;, this.tooltip.clickListener);
      }
      this.hammerManager = new Hammer.Manager(this.tooltip.el.nativeElement);
      this.hammerManager.add(new Hammer.Tap({ event: &apos;singletap&apos; }));
      this.hammerManager.on(&apos;singletap&apos;, this.toggleTooltip.bind(this));
    });
  }
  
  ngOnDestroy() {
    this.ngZone.runOutsideAngular(() =&gt; {
      if (this.hammerManager.get(&apos;singletap&apos;)) {
        this.hammerManager.off(&apos;singletap&apos;, this.toggleTooltip.bind(this));
      }
    });
  }
  
  @HostListener(&apos;document:click&apos;, [&apos;\$event.target&apos;])
  onClickOutside(target: Node) {
    if (!this.tooltip.el.nativeElement.contains(target) &amp;&amp; this.tooltip.active) {
      this.tooltip.deactivate();
    }
  }
  
  private toggleTooltip() {
    if (this.tooltip.active) {
      this.tooltip.deactivate();
    } else {
      this.tooltip.activate();
    }
  }
}`, `30609090288027718000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;hammerjs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Directive&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AfterViewInit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NgZone &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@angular/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Tooltip &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;primeng/tooltip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Directive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;[pTooltip][clickTrigger]&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TooltipClickDirective&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; OnDestroy &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; hammerManager&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; HammerManager&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt; 
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; tooltip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Tooltip&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; ngZone&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; NgZone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngAfterViewInit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ngZone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;runOutsideAngular&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;removeEventListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clickListener&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hammerManager &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hammer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Manager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hammerManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hammer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Tap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; event&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;singletap&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hammerManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;singletap&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toggleTooltip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token function&quot;&gt;ngOnDestroy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ngZone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;runOutsideAngular&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hammerManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;singletap&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hammerManager&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;off&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;singletap&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toggleTooltip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  @&lt;span class=&quot;token function&quot;&gt;HostListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;document:click&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;$event.target&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;onClickOutside&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;target&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Node&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nativeElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;target&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toggleTooltip&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deactivate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tooltip&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;activate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;import &amp;#39;hammerjs&amp;#39;;&lt;/code&gt; at the top of our &lt;code class=&quot;language-text&quot;&gt;tooltip-click.directive.ts&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HammerJS&lt;/strong&gt; needs a &lt;code class=&quot;language-text&quot;&gt;HammerManager&lt;/code&gt; instance to start managing &lt;code class=&quot;language-text&quot;&gt;touch gestures&lt;/code&gt;. We create our &lt;code class=&quot;language-text&quot;&gt;Hammer.Manager&lt;/code&gt; and pass in the &lt;code class=&quot;language-text&quot;&gt;DOM element&lt;/code&gt;, add a &lt;code class=&quot;language-text&quot;&gt;singletap&lt;/code&gt; event and listen to that event with &lt;code class=&quot;language-text&quot;&gt;toggleTooltip()&lt;/code&gt; bound to &lt;code class=&quot;language-text&quot;&gt;singletap&lt;/code&gt; event.&lt;/li&gt;
&lt;li&gt;We clean up our &lt;code class=&quot;language-text&quot;&gt;singletap&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;ngOnDestroy&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, we no longer trigger &lt;code class=&quot;language-text&quot;&gt;onMouseEnter&lt;/code&gt; with our &lt;code class=&quot;language-text&quot;&gt;singletap&lt;/code&gt; which makes it work pretty well on mobile friendly. Let’s go ahead and try it on our &lt;code class=&quot;language-text&quot;&gt;p-button&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;app.component.html&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;13793844875162487000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`&lt;p-button label=&amp;quot;PrimeNG Button&amp;quot; pTooltip=&amp;quot;I am a mobile friendly tooltip. Try on mobile screen and click me&amp;quot; clickTrigger&gt;&lt;/p-button&gt;`, `13793844875162487000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-html line-numbers&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p-button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;PrimeNG Button&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;pTooltip&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;I am a mobile friendly tooltip. Try on mobile screen and click me&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;clickTrigger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p-button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Go ahead and have your application refreshed, turn on &lt;code class=&quot;language-text&quot;&gt;responsive mode&lt;/code&gt; and check the &lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; is working perfectly on mobile viewports.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/wFyXBuZ.gif&quot; alt=&quot;mobile friendly&quot;&gt;
&lt;em&gt;&lt;code class=&quot;language-text&quot;&gt;Tooltip&lt;/code&gt; now works on mobile viewports&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;recap&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#recap&quot; aria-label=&quot;recap permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Recap&lt;/h3&gt;
&lt;p&gt;I hope you can learn something from this blog post. We’ve done hell of a lot of things in this post. We &lt;strong&gt;read the source code of a 3rd party library&lt;/strong&gt;, &lt;strong&gt;learn about HammerJS&lt;/strong&gt;, and most importantly, &lt;strong&gt;learn about how to use Directive to override/customize functionalities of a 3rd-party Component&lt;/strong&gt;. I also hope you can pick up a couple of tricks here and there from the blog post. Even though in my use-case, I only demonstrate on &lt;strong&gt;PrimeNG&lt;/strong&gt; ’s &lt;code class=&quot;language-text&quot;&gt;TooltipModule&lt;/code&gt; but the same concept can be applied to any 3rd-party UI Library which is open-source. Oh come on, &lt;code class=&quot;language-text&quot;&gt;hammerjs&lt;/code&gt; does not count 😢. Again, I wish you a Happy New Year. Thank you for reading 🚀. You can find the full code at &lt;a href=&quot;https://stackblitz.com/edit/primeng-tooltip-extend&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Stackblitz&lt;/a&gt; &lt;/p&gt;</content:encoded></item><item><title><![CDATA[NestJS + Typegoose]]></title><description><![CDATA[Today, I am going to share with you a workflow/technique (whatever you want to call it 🗿) that I’ve been using when I work with NestJS and…]]></description><link>https://nartc.netlify.com/blogs/nestjs-typegoose/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/nestjs-typegoose/</guid><pubDate>Tue, 10 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, I am going to share with you a workflow/technique (whatever you want to call it 🗿) that I’ve been using when I work with &lt;strong&gt;NestJS&lt;/strong&gt; and &lt;strong&gt;MongoDB&lt;/strong&gt;. This workflow leverages the power of &lt;strong&gt;TypeScript&lt;/strong&gt; and an &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt; package called &lt;a href=&quot;https://github.com/typegoose/typegoose&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Typegoose&lt;/a&gt;. This blog will be a quick one so let’s jump in.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’d assume you’re already familiar with &lt;strong&gt;NestJS&lt;/strong&gt; and &lt;strong&gt;MongoDB&lt;/strong&gt; (&lt;strong&gt;Mongoose&lt;/strong&gt; ODM to be exact)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Start off by initializing a new &lt;strong&gt;NestJS&lt;/strong&gt; application with &lt;code class=&quot;language-text&quot;&gt;@nestjs/cli&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;55288994026093150000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`nest new nest-typegoose
cd nest-typegoose`, `55288994026093150000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;nest new nest-typegoose
&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; nest-typegoose&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, delete &lt;code class=&quot;language-text&quot;&gt;app.controller.ts&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;app.service.ts&lt;/code&gt;. Modify your &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;3038442916603889700&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Module } from &apos;@nestjs/common&apos;;
- import { AppController } from &apos;./app.controller&apos;;
- import { AppService } from &apos;./app.service&apos;;

@Module({
  imports: [],
-  controllers: [AppController],
-  providers: [AppService],
})
export class AppModule {}`, `3038442916603889700`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;diff&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-diff line-numbers&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;import { Module } from &apos;@nestjs/common&apos;;
&lt;span class=&quot;token deleted-sign deleted&quot;&gt;- import { AppController } from &apos;./app.controller&apos;;
- import { AppService } from &apos;./app.service&apos;;
&lt;/span&gt;
@Module({
&lt;span class=&quot;token unchanged&quot;&gt;  imports: [],
&lt;/span&gt;&lt;span class=&quot;token deleted-sign deleted&quot;&gt;-  controllers: [AppController],
-  providers: [AppService],
&lt;/span&gt;})
export class AppModule {}&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, let’s install our &lt;code class=&quot;language-text&quot;&gt;dependencies&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;54825294925821950000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`yarn add @nestjs/mongoose mongoose @typegoose/typegoose
yarn add --dev @types/mongoose`, `54825294925821950000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; @nestjs/mongoose mongoose @typegoose/typegoose
&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; --dev @types/mongoose&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Alright, let’s get started. First thing first, let’s wire up our &lt;strong&gt;Mongo connection&lt;/strong&gt; using &lt;code class=&quot;language-text&quot;&gt;nestjs/mongoose&lt;/code&gt;. Open up &lt;code class=&quot;language-text&quot;&gt;app.module.ts&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;29269782212158013000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Module } from &apos;@nestjs/common&apos;;
import { MongooseModule } from &apos;@nestjs/mongoose&apos;;

@Module({
  imports: [
    MongooseModule.forRoot(&apos;mongodb://localhost:27017/nestjs-typegoose&apos;, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
    }),
  ],
})
export class AppModule {}`, `29269782212158013000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Module &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; MongooseModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/mongoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    MongooseModule&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forRoot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017/nestjs-typegoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;Again, I assume you’re familiar with &lt;strong&gt;MongoDB&lt;/strong&gt; and are able to spin up an instance of &lt;strong&gt;MongoDB&lt;/strong&gt; running locally either installing &lt;strong&gt;MongoDB&lt;/strong&gt; on your machine or using &lt;strong&gt;Docker&lt;/strong&gt;. I’d recommend the latter.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, you can try running your server: &lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;32023186347640540000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`yarn start:dev`, `32023186347640540000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;yarn&lt;/span&gt; start:dev&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;you should see the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;17885570228114590000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`10:14:05 PM - File change detected. Starting incremental compilation...


10:14:05 PM - Found 0 errors. Watching for file changes.
[Nest] 16093   - 12/10/2019, 10:14:05 PM   [NestFactory] Starting Nest application...
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [InstanceLoader] AppModule dependencies initialized +23ms
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [InstanceLoader] MongooseModule dependencies initialized +0ms
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [InstanceLoader] MongooseCoreModule dependencies initialized +15ms
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [NestApplication] Nest application successfully started +7ms`, `17885570228114590000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shellscript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shellscript line-numbers&quot;&gt;&lt;code class=&quot;language-shellscript&quot;&gt;10:14:05 PM - File change detected. Starting incremental compilation...


10:14:05 PM - Found 0 errors. Watching for file changes.
[Nest] 16093   - 12/10/2019, 10:14:05 PM   [NestFactory] Starting Nest application...
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [InstanceLoader] AppModule dependencies initialized +23ms
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [InstanceLoader] MongooseModule dependencies initialized +0ms
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [InstanceLoader] MongooseCoreModule dependencies initialized +15ms
[Nest] 16093   - 12/10/2019, 10:14:06 PM   [NestApplication] Nest application successfully started +7ms&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s create a couple of files:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;7115378549453811000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`mkdir src/shared # I like to have a &amp;quot;shared&amp;quot; directory. You can name it whatever you like
touch src/shared/base.model.ts # a base model file
touch src/shared/base.service.ts # a base service file. I&apos;ll explain more about this in a bit`, `7115378549453811000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; src/shared &lt;span class=&quot;token comment&quot;&gt;# I like to have a &quot;shared&quot; directory. You can name it whatever you like&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; src/shared/base.model.ts &lt;span class=&quot;token comment&quot;&gt;# a base model file&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; src/shared/base.service.ts &lt;span class=&quot;token comment&quot;&gt;# a base service file. I&apos;ll explain more about this in a bit&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open up the &lt;code class=&quot;language-text&quot;&gt;base.model.ts&lt;/code&gt; then put in the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;54845101855532790000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Schema } from &apos;mongoose&apos;;
import { buildSchema, prop } from &apos;@typegoose/typegoose&apos;;

export abstract class BaseModel {
  @prop()
  createdDate?: Date; // provided by timestamps
  @prop()
  updatedDate?: Date; // provided by timestamps
  id?: string; // is actually model._id getter
  // add more to a base model if you want.

  static get schema(): Schema {
    return buildSchema(this as any, {
      timestamps: true,
      toJSON: {
        getters: true,
        virtuals: true,
      },
    });
  }

  static get modelName(): string {
    return this.name;
  }
}`, `54845101855532790000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Schema &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mongoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; buildSchema&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; prop &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@typegoose/typegoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseModel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  createdDate&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// provided by timestamps&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  updatedDate&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// provided by timestamps&lt;/span&gt;
  id&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// is actually model._id getter&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// add more to a base model if you want.&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;schema&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Schema &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;buildSchema&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      timestamps&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      toJSON&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        getters&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        virtuals&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;modelName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s go through the code to understand it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create an &lt;code class=&quot;language-text&quot;&gt;abstract&lt;/code&gt; class so it &lt;strong&gt;cannot&lt;/strong&gt; be initialized (&lt;code class=&quot;language-text&quot;&gt;new() up&lt;/code&gt;) accidentally. &lt;code class=&quot;language-text&quot;&gt;abstract&lt;/code&gt; also annotates that this class is only meant to be extended.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;createdDate&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;updatedDate&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;id&lt;/code&gt; are the three fields that &lt;strong&gt;ALL&lt;/strong&gt; of my &lt;strong&gt;Domain Models&lt;/strong&gt; (or &lt;strong&gt;Data Model&lt;/strong&gt; or &lt;strong&gt;Mongo Model&lt;/strong&gt;, it’s up to you) will have. &lt;code class=&quot;language-text&quot;&gt;createdDate&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;updatedDate&lt;/code&gt; are provided automatically if you turn &lt;code class=&quot;language-text&quot;&gt;timestamps&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;true&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;id&lt;/code&gt; is actually a getter of &lt;code class=&quot;language-text&quot;&gt;_id&lt;/code&gt; so it’s always there, but to be able to grab &lt;code class=&quot;language-text&quot;&gt;id&lt;/code&gt; when paired with &lt;code class=&quot;language-text&quot;&gt;.lean()&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;.toJSON()&lt;/code&gt;, you need to set the &lt;code class=&quot;language-text&quot;&gt;toJSON: {...}&lt;/code&gt; option as shown.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@prop()&lt;/code&gt; annotates the field that it’s part of the &lt;code class=&quot;language-text&quot;&gt;schema&lt;/code&gt;. Learn more at &lt;a href=&quot;https://github.com/typegoose/typegoose&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;typegoose&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;static get schema()&lt;/code&gt;. The magic is here. With the latest release, &lt;code class=&quot;language-text&quot;&gt;typegoose&lt;/code&gt; actually makes their API more &lt;em&gt;Functional&lt;/em&gt; in a way that they expose &lt;strong&gt;functions&lt;/strong&gt; like &lt;code class=&quot;language-text&quot;&gt;getModelForClass()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;buildSchema()&lt;/code&gt; separately instead of having them as &lt;code class=&quot;language-text&quot;&gt;static functions&lt;/code&gt; on the &lt;code class=&quot;language-text&quot;&gt;Typegoose&lt;/code&gt; class which makes this technique/pattern/workflow possible. Why do we need &lt;code class=&quot;language-text&quot;&gt;buildSchema()&lt;/code&gt;? Well, &lt;code class=&quot;language-text&quot;&gt;MongooseModule&lt;/code&gt; from &lt;code class=&quot;language-text&quot;&gt;nestjs/mongoose&lt;/code&gt; requires two things to create a certain &lt;code class=&quot;language-text&quot;&gt;MongooseModel&lt;/code&gt; for you: &lt;code class=&quot;language-text&quot;&gt;Schema&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;buildSchema()&lt;/code&gt; will help us get the &lt;code class=&quot;language-text&quot;&gt;Schema&lt;/code&gt;, the &lt;code class=&quot;language-text&quot;&gt;name&lt;/code&gt; can be anything. How it works is we call &lt;code class=&quot;language-text&quot;&gt;buildSchema()&lt;/code&gt; and pass in &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt; in this case, inside of a &lt;code class=&quot;language-text&quot;&gt;static&lt;/code&gt; method, is the actual class itself which invokes &lt;code class=&quot;language-text&quot;&gt;schema&lt;/code&gt; getter, making it possible to put &lt;code class=&quot;language-text&quot;&gt;get schema()&lt;/code&gt; on the &lt;code class=&quot;language-text&quot;&gt;abstract&lt;/code&gt; class so we can &lt;strong&gt;DRY&lt;/strong&gt; up a bit here. Before, we need to write methods to grab &lt;code class=&quot;language-text&quot;&gt;schema&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;modelName&lt;/code&gt; for each &lt;strong&gt;Domain Model&lt;/strong&gt; class which is kinda &lt;em&gt;boiler-platey&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;static get modelName()&lt;/code&gt;. Pretty simple here. We just return &lt;code class=&quot;language-text&quot;&gt;this.name&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt;, again in the context of a &lt;code class=&quot;language-text&quot;&gt;static&lt;/code&gt; method, points to the actual class so &lt;code class=&quot;language-text&quot;&gt;this.name&lt;/code&gt; returns the class name. However, if you’re skeptical, you might want to return something else or just have a function that will do some magic to return some meaningful name for your &lt;code class=&quot;language-text&quot;&gt;MongooseModel&lt;/code&gt;. I tend to return &lt;code class=&quot;language-text&quot;&gt;this.name&lt;/code&gt; here because I use &lt;code class=&quot;language-text&quot;&gt;this.name&lt;/code&gt; on couple more places like &lt;code class=&quot;language-text&quot;&gt;Swagger UI&lt;/code&gt; to annotate the &lt;code class=&quot;language-text&quot;&gt;Tags&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now we have our &lt;code class=&quot;language-text&quot;&gt;BaseModel&lt;/code&gt;, let’s take care of &lt;code class=&quot;language-text&quot;&gt;BaseService&lt;/code&gt;. Open &lt;code class=&quot;language-text&quot;&gt;base.service.ts&lt;/code&gt; and paste in the following code (or you can type if you like). But before showing the code, I’d like to explain a bit.&lt;/p&gt;
&lt;p&gt;Why &lt;code class=&quot;language-text&quot;&gt;BaseService&lt;/code&gt;? I used to be a fan of &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design#the-repository-pattern&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Repository Pattern&lt;/a&gt; and &lt;code class=&quot;language-text&quot;&gt;base.service.ts&lt;/code&gt; would have been &lt;code class=&quot;language-text&quot;&gt;base.repository.ts&lt;/code&gt; if I was still a fan. Don’t get me wrong, I still like the pattern. However, working with an &lt;strong&gt;ODM&lt;/strong&gt; like &lt;code class=&quot;language-text&quot;&gt;mongoose&lt;/code&gt;, I feel like the &lt;code class=&quot;language-text&quot;&gt;MongooseModel&lt;/code&gt; kind of acts like a &lt;code class=&quot;language-text&quot;&gt;Repository&lt;/code&gt; already. Hence, I tend to &lt;em&gt;get rid&lt;/em&gt; of the &lt;strong&gt;Repository Layer&lt;/strong&gt; to decrease the amount of abstractions I have throughout the application. Again, it depends on the characteristics of the application’s requirements. I just want to get my point across and want to explain why I do things the way I do things. Now that we’re clear on this, let’s move on:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;84146598353928880000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { InternalServerErrorException } from &apos;@nestjs/common&apos;;
import { DocumentType, ReturnModelType } from &apos;@typegoose/typegoose&apos;;
import { AnyParamConstructor } from &apos;@typegoose/typegoose/lib/types&apos;;
import { MongoError } from &apos;mongodb&apos;;
import { DocumentQuery, Types, Query } from &apos;mongoose&apos;;
import { BaseModel } from &apos;./base.model&apos;;

type QueryList&lt;T extends BaseModel&gt; = DocumentQuery&lt;
  Array&lt;DocumentType&lt;T&gt;&gt;,
  DocumentType&lt;T&gt;
&gt;;
type QueryItem&lt;T extends BaseModel&gt; = DocumentQuery&lt;
  DocumentType&lt;T&gt;,
  DocumentType&lt;T&gt;
&gt;;

export abstract class BaseService&lt;T extends BaseModel&gt; {
  protected model: ReturnModelType&lt;AnyParamConstructor&lt;T&gt;&gt;;

  protected constructor(model: ReturnModelType&lt;AnyParamConstructor&lt;T&gt;&gt;) {
    this.model = model;
  }

  protected static throwMongoError(err: MongoError): void {
    throw new InternalServerErrorException(err, err.errmsg);
  }

  protected static toObjectId(id: string): Types.ObjectId {
    try {
      return Types.ObjectId(id);
    } catch (e) {
      this.throwMongoError(e);
    }
  }

  createModel(doc?: Partial&lt;T&gt;): T {
    return new this.model(doc);
  }

  findAll(filter = {}): QueryList&lt;T&gt; {
    return this.model.find(filter);
  }

  async findAllAsync(filter = {}): Promise&lt;Array&lt;DocumentType&lt;T&gt;&gt;&gt; {
    try {
      return await this.findAll(filter).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  findOne(filter = {}): QueryItem&lt;T&gt; {
    return this.model.findOne(filter);
  }

  async findOneAsync(filter = {}): Promise&lt;DocumentType&lt;T&gt;&gt; {
    try {
      return await this.findOne(filter).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  findById(id: string): QueryItem&lt;T&gt; {
    return this.model.findById(BaseService.toObjectId(id));
  }

  async findByIdAsync(id: string): Promise&lt;DocumentType&lt;T&gt;&gt; {
    try {
      return await this.findById(id).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  async create(item: T): Promise&lt;DocumentType&lt;T&gt;&gt; {
    try {
      return await this.model.create(item);
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  delete(filter = {}): QueryItem&lt;T&gt; {
    return this.model.findOneAndDelete(filter);
  }

  async deleteAsync(filter = {}): Promise&lt;DocumentType&lt;T&gt;&gt; {
    try {
      return await this.delete(filter).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  deleteById(id: string): QueryItem&lt;T&gt; {
    return this.model.findByIdAndDelete(BaseService.toObjectId(id));
  }

  async deleteByIdAsync(id: string): Promise&lt;DocumentType&lt;T&gt;&gt; {
    try {
      return await this.deleteById(id).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  update(item: T): QueryItem&lt;T&gt; {
    return this.model.findByIdAndUpdate(BaseService.toObjectId(item.id), item, {
      new: true,
    });
  }

  async updateAsync(item: T): Promise&lt;DocumentType&lt;T&gt;&gt; {
    try {
      return await this.update(item).exec();
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }

  count(filter = {}): Query&lt;number&gt; {
    return this.model.count(filter);
  }

  async countAsync(filter = {}): Promise&lt;number&gt; {
    try {
      return await this.count(filter);
    } catch (e) {
      BaseService.throwMongoError(e);
    }
  }
}`, `84146598353928880000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; InternalServerErrorException &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DocumentType&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ReturnModelType &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@typegoose/typegoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AnyParamConstructor &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@typegoose/typegoose/lib/types&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; MongoError &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; DocumentQuery&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Types&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Query &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;mongoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BaseModel &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./base.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; QueryList&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseModel&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DocumentQuery&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; QueryItem&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseModel&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DocumentQuery&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;
  DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseService&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseModel&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; model&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ReturnModelType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnyParamConstructor&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;model&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ReturnModelType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;AnyParamConstructor&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; MongoError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InternalServerErrorException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errmsg&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toObjectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Types&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ObjectId &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Types&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ObjectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;createModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Partial&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;this&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;findAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; QueryList&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findAllAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;findOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; QueryItem&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findOneAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; QueryItem&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toObjectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;findByIdAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; QueryItem&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findOneAndDelete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;deleteAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;deleteById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; QueryItem&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findByIdAndDelete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toObjectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;deleteByIdAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; QueryItem&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findByIdAndUpdate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toObjectId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; item&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DocumentType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;item&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Query&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;countAsync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      BaseService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;throwMongoError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Whew, I know it’s a lot of code. But what did we do here?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Again, another &lt;code class=&quot;language-text&quot;&gt;abstract&lt;/code&gt; class to make sure we do not &lt;code class=&quot;language-text&quot;&gt;new()&lt;/code&gt; this one up accidentally. This takes in a &lt;strong&gt;Type Parameter&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;T extends BaseModel&lt;/code&gt;. This is where &lt;strong&gt;TypeScript&lt;/strong&gt; comes in with its &lt;code class=&quot;language-text&quot;&gt;Advanced Types&lt;/code&gt;. Here, we explicitly say &lt;code class=&quot;language-text&quot;&gt;T extends BaseModel&lt;/code&gt; so that we can only pass actual &lt;strong&gt;Domain Model&lt;/strong&gt; classes to this &lt;code class=&quot;language-text&quot;&gt;BaseService&lt;/code&gt;, just another &lt;em&gt;safety&lt;/em&gt; thing that you could get with &lt;strong&gt;TypeScript&lt;/strong&gt; to prevent passing &lt;strong&gt;ANY&lt;/strong&gt; as the &lt;strong&gt;Type Parameter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Declare a &lt;code class=&quot;language-text&quot;&gt;protected&lt;/code&gt; field called &lt;code class=&quot;language-text&quot;&gt;model&lt;/code&gt; with the type of &lt;code class=&quot;language-text&quot;&gt;ReturnModelType&amp;lt;AnyParamConstructor&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt;. Wow, such a mouthful. What &lt;code class=&quot;language-text&quot;&gt;ReturnModelType&amp;lt;AnyParamConstructor&amp;lt;T&amp;gt;&amp;gt;&lt;/code&gt; really is is just the type that &lt;code class=&quot;language-text&quot;&gt;mongoose.model()&lt;/code&gt; will return. &lt;strong&gt;Wait, isn’t there &lt;code class=&quot;language-text&quot;&gt;Model&amp;lt;T&amp;gt;&lt;/code&gt;?&lt;/strong&gt;, yes there is. But &lt;code class=&quot;language-text&quot;&gt;Model&amp;lt;T&amp;gt;&lt;/code&gt; expects &lt;code class=&quot;language-text&quot;&gt;T&lt;/code&gt; to be an &lt;code class=&quot;language-text&quot;&gt;interface&lt;/code&gt; that &lt;code class=&quot;language-text&quot;&gt;extends mongoose.Document&lt;/code&gt;. With &lt;code class=&quot;language-text&quot;&gt;typegoose&lt;/code&gt;, everything is &lt;code class=&quot;language-text&quot;&gt;class&lt;/code&gt; here so we can’t really utilize the &lt;em&gt;simpler&lt;/em&gt; way with &lt;code class=&quot;language-text&quot;&gt;Model&amp;lt;T&amp;gt;&lt;/code&gt;. Another notion is making the &lt;code class=&quot;language-text&quot;&gt;model&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;protected&lt;/code&gt; means only the sub-class can have access to this field so we don’t expose &lt;code class=&quot;language-text&quot;&gt;someService.model&lt;/code&gt; in any other layers of the application (like the &lt;strong&gt;Controller Layer&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;Setup a &lt;code class=&quot;language-text&quot;&gt;protected constructor&lt;/code&gt;. Pretty straight forward here.&lt;/li&gt;
&lt;li&gt;Setup a plethora of methods that wrap around &lt;code class=&quot;language-text&quot;&gt;mongoose.Model&lt;/code&gt;’s methods and return appropriate types. You’ve probably already noticed that we have &lt;strong&gt;two&lt;/strong&gt; versions for each method. The first version returns a &lt;code class=&quot;language-text&quot;&gt;DocumentQuery&lt;/code&gt; which allows you to &lt;strong&gt;chain&lt;/strong&gt; methods to further: &lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;project&lt;/code&gt;, and some other stuffs like &lt;code class=&quot;language-text&quot;&gt;populate&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;lean&lt;/code&gt;. The 2nd version (&lt;code class=&quot;language-text&quot;&gt;async&lt;/code&gt; version) helps with situations where you don’t care about any other &lt;strong&gt;chainable&lt;/strong&gt; methods and just want to grab the data quickly. The &lt;code class=&quot;language-text&quot;&gt;async&lt;/code&gt; version will also have error handler where we throw an &lt;code class=&quot;language-text&quot;&gt;InternalServerErrorException&lt;/code&gt; with the &lt;code class=&quot;language-text&quot;&gt;MongoError&lt;/code&gt;. I will go back to this in the &lt;strong&gt;bonus&lt;/strong&gt; section.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;You can abstract more methods if you want to but for me, these work for most cases.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now that we have a &lt;code class=&quot;language-text&quot;&gt;BaseModel&lt;/code&gt; and a &lt;code class=&quot;language-text&quot;&gt;BaseService&lt;/code&gt; both of which we can use to extend our &lt;strong&gt;Domain Model&lt;/strong&gt; classes and respective &lt;strong&gt;Services&lt;/strong&gt;. Let’s try creating one real quick here:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;26175391343769027000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`nest generate module product
nest generate service product --no-spec
nest generate controller product --no-spec

touch src/product/product.model.ts`, `26175391343769027000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;nest generate module product
nest generate &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt; product --no-spec
nest generate controller product --no-spec

&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; src/product/product.model.ts&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open &lt;code class=&quot;language-text&quot;&gt;product.model.ts&lt;/code&gt; and paste/type in the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;40366673697795430000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { prop } from &apos;@typegoose/typegoose&apos;;
import { BaseModel } from &apos;../shared/base.model&apos;;

export class Product extends BaseModel {
  @prop()
  name: string;
  @prop()
  description: string;
  @prop()
  price: number;
}`, `40366673697795430000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; prop &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@typegoose/typegoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BaseModel &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../shared/base.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Product&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseModel&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  description&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  price&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We extend &lt;code class=&quot;language-text&quot;&gt;BaseModel&lt;/code&gt; and define 3 fields on our &lt;code class=&quot;language-text&quot;&gt;Product&lt;/code&gt;. These are arbitrary. Next, open &lt;code class=&quot;language-text&quot;&gt;product.module.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;47279588157391400000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Module } from &apos;@nestjs/common&apos;;
import { MongooseModule } from &apos;@nestjs/mongoose&apos;;
import { ProductController } from &apos;./product.controller&apos;;
import { Product } from &apos;./product.model&apos;;
import { ProductService } from &apos;./product.service&apos;;

@Module({
  imports: [
    MongooseModule.forFeature([
      { name: Product.modelName, schema: Product.schema },
    ]),
  ],
  providers: [ProductService],
  controllers: [ProductController],
})
export class ProductModule {}`, `47279588157391400000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Module &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; MongooseModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/mongoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ProductController &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./product.controller&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Product &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./product.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ProductService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./product.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  imports&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    MongooseModule&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forFeature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Product&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;modelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; schema&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Product&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;schema &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;  providers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ProductService&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  controllers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ProductController&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProductModule&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The important piece here is we call &lt;code class=&quot;language-text&quot;&gt;MongooseModule.forFeature&lt;/code&gt; and pass in an array of &lt;code class=&quot;language-text&quot;&gt;models&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;MongooseModule.forFeature&lt;/code&gt; will grab the current &lt;code class=&quot;language-text&quot;&gt;mongoose.Connection&lt;/code&gt; and add the models passed in then provide those models in &lt;strong&gt;NestJS’s IoC Container&lt;/strong&gt; (for &lt;strong&gt;Dependency Injection&lt;/strong&gt;). Now you can see that the &lt;code class=&quot;language-text&quot;&gt;schema&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;modelName&lt;/code&gt; are important and the &lt;code class=&quot;language-text&quot;&gt;BaseModel&lt;/code&gt; helps quite a bit here.&lt;/p&gt;
&lt;p&gt;Next, let’s open &lt;code class=&quot;language-text&quot;&gt;product.service.ts&lt;/code&gt; and &lt;strong&gt;type&lt;/strong&gt; the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;14787733423529925000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Injectable } from &apos;@nestjs/common&apos;;
import { InjectModel } from &apos;@nestjs/mongoose&apos;;
import { ReturnModelType } from &apos;@typegoose/typegoose/lib/types&apos;;
import { BaseService } from &apos;../shared/base.service&apos;;
import { Product } from &apos;./product.model&apos;;

@Injectable()
export class ProductService extends BaseService&lt;Product&gt; {
  constructor(
    @InjectModel(Product.modelName)
    private readonly productModel: ReturnModelType&lt;typeof Product&gt;,
  ) {
    super(productModel);
  }
}`, `14787733423529925000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Injectable &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; InjectModel &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/mongoose&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ReturnModelType &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@typegoose/typegoose/lib/types&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; BaseService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../shared/base.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Product &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./product.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Injectable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProductService&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BaseService&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Product&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token parameter&quot;&gt;@&lt;span class=&quot;token function&quot;&gt;InjectModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Product&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;modelName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; productModel&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ReturnModelType&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; Product&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;productModel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And that’s it. See why I bolded &lt;strong&gt;type&lt;/strong&gt;. With the &lt;code class=&quot;language-text&quot;&gt;BaseService&lt;/code&gt; all setup, your &lt;code class=&quot;language-text&quot;&gt;ProductService&lt;/code&gt; now has all the methods available to use. However, most of the cases you would need to add additional methods that are a bit more &lt;em&gt;specialized&lt;/em&gt; for specific business logic.&lt;/p&gt;
&lt;p&gt;Finally, let’s just inject &lt;code class=&quot;language-text&quot;&gt;ProductService&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;product.controller.ts&lt;/code&gt; and start hacking:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;48376661569650810000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { Controller } from &apos;@nestjs/common&apos;;
import { ProductService } from &apos;./product.service&apos;;

@Controller(&apos;product&apos;)
export class ProductController {
  constructor(private readonly productService: ProductService) {}
}`, `48376661569650810000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Controller &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ProductService &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./product.service&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Controller&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;product&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProductController&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;readonly&lt;/span&gt; productService&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProductService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though this is a really minimal example but I hope it shows you how to utilize &lt;strong&gt;TypeScript&lt;/strong&gt; and &lt;strong&gt;Typegoose&lt;/strong&gt; to abstract some &lt;strong&gt;base&lt;/strong&gt; to speed up your development processes. Moreover, you can even have a &lt;code class=&quot;language-text&quot;&gt;BaseController&lt;/code&gt; that will have a &lt;code class=&quot;language-text&quot;&gt;protected baseService&lt;/code&gt; that will cover your basic &lt;code class=&quot;language-text&quot;&gt;CRUD&lt;/code&gt; functionalities. That’s it for me today, guys. Have fun and good luck 🍀&lt;/p&gt;
&lt;h2 id=&quot;bonus&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#bonus&quot; aria-label=&quot;bonus permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Bonus&lt;/h2&gt;
&lt;p&gt;Remember the &lt;code class=&quot;language-text&quot;&gt;throwMongoError&lt;/code&gt; piece? Now I will show you how you can have a more uniformed way of handling &lt;code class=&quot;language-text&quot;&gt;HttpException&lt;/code&gt; (&lt;code class=&quot;language-text&quot;&gt;InternalServerErrorException&lt;/code&gt; is an instance of &lt;code class=&quot;language-text&quot;&gt;HttpException&lt;/code&gt;) using &lt;strong&gt;NestJS Exception Filters&lt;/strong&gt;. Let’s get started, shall we?&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;95542804729806160000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`mkdir src/shared/filters
touch src/shared/filters/http-exception.filter.ts
touch src/shared/api-exception.model.ts`, `95542804729806160000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; src/shared/filters
&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; src/shared/filters/http-exception.filter.ts
&lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; src/shared/api-exception.model.ts&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Open &lt;code class=&quot;language-text&quot;&gt;api-exception.model.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;2573270333450761000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { HttpStatus } from &apos;@nestjs/common&apos;;

export class ApiException {
  statusCode?: number;
  message?: string;
  status?: string;
  error?: string;
  errors?: any;
  timestamp?: string;
  path?: string;
  stack?: string;

  constructor(
    message: string,
    error: string,
    stack: string,
    errors: any,
    path: string,
    statusCode: number,
  ) {
    this.message = message;
    this.error = error;
    this.stack = stack;
    this.errors = errors;
    this.path = path;
    this.timestamp = new Date().toISOString();
    this.statusCode = statusCode;
    this.status = HttpStatus[statusCode];
  }
}`, `2573270333450761000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; HttpStatus &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ApiException&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  statusCode&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  message&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  status&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  error&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  errors&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  timestamp&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  path&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  stack&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token parameter&quot;&gt;message&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    stack&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    errors&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    statusCode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stack &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; stack&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; errors&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;timestamp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toISOString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;statusCode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; statusCode&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; HttpStatus&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;statusCode&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We create an &lt;code class=&quot;language-text&quot;&gt;ApiException&lt;/code&gt; class (you can call it whatever you want) to model our &lt;strong&gt;API Error&lt;/strong&gt;. Self-explanatory, right?&lt;/p&gt;
&lt;p&gt;Then open &lt;code class=&quot;language-text&quot;&gt;http-exception.filter.ts&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;96603598069906370000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
} from &apos;@nestjs/common&apos;;
import { Response } from &apos;express&apos;;
import { ApiException } from &apos;../api-exception.model&apos;;

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(error: any, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const res = ctx.getResponse() as Response;
    const req = ctx.getRequest();
    const statusCode = error.getStatus();
    const stacktrace = error.stack;
    const errorName = error.response.name || error.response.error || error.name;
    const errors = error.response.errors || null;
    const path = req ? req.url : null;

    if (statusCode === HttpStatus.UNAUTHORIZED) {
      if (typeof error.response !== &apos;string&apos;) {
        error.response.message =
          error.response.message ||
          &apos;You do not have permission to access this resource&apos;;
      }
    }

    const exception = new ApiException(
      error.response.message,
      errorName,
      stacktrace,
      errors,
      path,
      statusCode,
    );
    res.status(statusCode).json(exception);
  }
}`, `96603598069906370000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ArgumentsHost&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Catch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  ExceptionFilter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  HttpException&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  HttpStatus&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/common&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Response &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ApiException &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../api-exception.model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HttpException&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HttpExceptionFilter&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;implements&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ExceptionFilter&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ArgumentsHost&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ctx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; host&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;switchToHttp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getResponse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Response&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; statusCode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStatus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; stacktrace &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stack&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; errorName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; errors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; req &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;statusCode &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; HttpStatus&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;UNAUTHORIZED&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;string&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
          error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;
          &lt;span class=&quot;token string&quot;&gt;&apos;You do not have permission to access this resource&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; exception &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ApiException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      errorName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      stacktrace&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      errors&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      path&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      statusCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;statusCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;exception&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So if you recall, we throw an &lt;code class=&quot;language-text&quot;&gt;InternalServerErrorException&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;throwMongoError&lt;/code&gt; which will be caught by this &lt;code class=&quot;language-text&quot;&gt;HttpExceptionFilter&lt;/code&gt; because we decorate it with &lt;code class=&quot;language-text&quot;&gt;@Catch(HttpException)&lt;/code&gt;. That’s how &lt;code class=&quot;language-text&quot;&gt;Exception Filter&lt;/code&gt; works. You can &lt;code class=&quot;language-text&quot;&gt;@Catch()&lt;/code&gt; some very specific error classes if you desire to. &lt;code class=&quot;language-text&quot;&gt;Exception Filter&lt;/code&gt; allows you to have access to the &lt;code class=&quot;language-text&quot;&gt;ExecutionContext&lt;/code&gt; which lets you know that your application is a &lt;code class=&quot;language-text&quot;&gt;HttpServer&lt;/code&gt; which has access to &lt;code class=&quot;language-text&quot;&gt;Request&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Response&lt;/code&gt; (from &lt;code class=&quot;language-text&quot;&gt;express&lt;/code&gt;). Then from those information, you can construct an uniformed error and call &lt;code class=&quot;language-text&quot;&gt;res.status(Status).json()&lt;/code&gt; to return a meaningful, uniformed error to the client. The client will always get the same shape of error which allows them to handle the error more efficiently and consistently.&lt;/p&gt;
&lt;p&gt;To activate the &lt;code class=&quot;language-text&quot;&gt;HttpExceptionFilter&lt;/code&gt;, open &lt;code class=&quot;language-text&quot;&gt;main.ts&lt;/code&gt; and add the following line:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;5774806363084162000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import { NestFactory } from &apos;@nestjs/core&apos;;
import { AppModule } from &apos;./app.module&apos;;
import { HttpExceptionFilter } from &apos;./shared/filters/http-exception.filter&apos;;

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();`, `5774806363084162000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; NestFactory &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@nestjs/core&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; AppModule &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./app.module&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; HttpExceptionFilter &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./shared/filters/http-exception.filter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bootstrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; NestFactory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;AppModule&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useGlobalFilters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HttpExceptionFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;bootstrap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, all of your &lt;code class=&quot;language-text&quot;&gt;HttpException&lt;/code&gt; thrown from &lt;strong&gt;ANYWHERE&lt;/strong&gt; in the application will be filtered by &lt;code class=&quot;language-text&quot;&gt;HttpExceptionFilter&lt;/code&gt; and will be returned with an instance of &lt;code class=&quot;language-text&quot;&gt;ApiException&lt;/code&gt; 👍&lt;/p&gt;</content:encoded></item><item><title><![CDATA[A brief introduction to AutoMapper in TypeScript]]></title><description><![CDATA[Hi everyone, it’s been exactly a month (again) since my last blog 😄 and you’re probably getting bored of me saying that. Last month, I…]]></description><link>https://nartc.netlify.com/blogs/introduction-to-automapper-typescript/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/introduction-to-automapper-typescript/</guid><pubDate>Sat, 16 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hi everyone, it’s been exactly a month (again) since my last blog 😄 and you’re probably getting bored of me saying that. Last month, I published a blog explaining why I wanted to create an &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; library in &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt;. In today’s blog, I am going to dive deeper into how it works in &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; by officially introducing my library for the first time: &lt;strong&gt;@nartc/automapper&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Check it out on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nartc/mapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/@nartc/automapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;npm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-problem&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-problem&quot; aria-label=&quot;the problem permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Problem&lt;/h2&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; getting more and more popular, we start seeing a lot more Server-Side projects written in &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; and &lt;em&gt;problems with exposing the proper data&lt;/em&gt; slowly concerns many developers who are working on those projects. The concern shows clearer in particular with building &lt;strong&gt;APIs&lt;/strong&gt; using &lt;a href=&quot;https://en.wikipedia.org/wiki/Domain-driven_design&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;DDD&lt;/a&gt; (Domain Driven Design) with a lot of &lt;a href=&quot;https://en.wikipedia.org/wiki/Data_transfer_object&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;DTOs&lt;/a&gt; / &lt;a href=&quot;https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;VMs&lt;/a&gt; (Data Transfer Object or View Model, these two terms can be used interchangeably). In other words, you do not want to expose your &lt;a href=&quot;https://en.wikipedia.org/wiki/Domain_model&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Domain Model&lt;/a&gt; outside of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Persistence_(computer_science)#Persistence_layers&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Persistence Layer&lt;/a&gt; just in case the &lt;strong&gt;Application Layer&lt;/strong&gt; in &lt;a href=&quot;https://en.wikipedia.org/wiki/Multitier_architecture&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Multitier Architecture&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And in &lt;code class=&quot;language-text&quot;&gt;JavaScript&lt;/code&gt;, being a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/Dynamic_programming_language&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Dynamic Programming Language&lt;/a&gt;, the above problem ”&lt;em&gt;can be done&lt;/em&gt;” quite easily because there is nothing stopping you from assigning values to your heart content. However, doing so blindly or mindlessly can cost you your &lt;strong&gt;maintainability&lt;/strong&gt; to your code-base which is extremely dangerous and well, costly. On the other hand, doing so repeatedly will be prone to errors and eventually all of these ”&lt;em&gt;manual mappings&lt;/em&gt;” will become &lt;strong&gt;tech debts&lt;/strong&gt; that are really hard to &lt;em&gt;repay&lt;/em&gt;, especially &lt;strong&gt;Complex Mappings&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;use-case&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#use-case&quot; aria-label=&quot;use case permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Use-case&lt;/h2&gt;
&lt;p&gt;Let’s assume you are building a minimal &lt;strong&gt;AirBnB clone&lt;/strong&gt; and you plan to have the following &lt;strong&gt;Domain Models&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Person&lt;/li&gt;
&lt;li&gt;Listing&lt;/li&gt;
&lt;li&gt;Booking&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Real scenario will have many more &lt;strong&gt;Domain Models&lt;/strong&gt; like: &lt;code class=&quot;language-text&quot;&gt;Notification&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Message&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Transaction&lt;/code&gt; etc… to accommodate such platform. Here, I take out all the transaction-related to simplify this blog post.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and you want to your platform able to do the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Anyone can register to become a &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; in your application.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; has two main &lt;code class=&quot;language-text&quot;&gt;Role&lt;/code&gt;: &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Host&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Signed up &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; will have their &lt;code class=&quot;language-text&quot;&gt;Role&lt;/code&gt; default to &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; role can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Look at all &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create a &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;pastBookings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save a &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;wishlist&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Save a &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;lastViews&lt;/code&gt; list&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; will become a &lt;code class=&quot;language-text&quot;&gt;Host&lt;/code&gt; after they create their first &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; and can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create more &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Respond to &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; request&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;From the above requirements, you can see that our &lt;strong&gt;Domain Models&lt;/strong&gt; are having quite a complex &lt;strong&gt;relationship&lt;/strong&gt; and &lt;strong&gt;circular dependencies&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; can have a list of &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;lastViews&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;wishlist&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; can have a list of &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;pastBookings&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; must have a &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; as &lt;code class=&quot;language-text&quot;&gt;host&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; must have both &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; as &lt;code class=&quot;language-text&quot;&gt;user&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;host&lt;/code&gt;, and also &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; as &lt;code class=&quot;language-text&quot;&gt;listing&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;Let us all assume that we don’t have to worry about &lt;strong&gt;Domain Models&lt;/strong&gt; relationships like One-One, One-Many and Many-Many. We only focus on exposing our &lt;strong&gt;Models&lt;/strong&gt; to the consumers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s look at our &lt;strong&gt;models&lt;/strong&gt; in code:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;6725455617070941000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Person.ts

class Address {
  street: string;
  city: string;
  state: string;
  zip: string;
}

class Profile {
  firstName: string;
  lastName: string;
  bio: string;
  phone: string;
  address: Address;
}

enum Role {
  User = &amp;quot;user&amp;quot;,
  Host = &amp;quot;host&amp;quot;,
}

class Person {
  email: string;
  password: string;
  profile: Profile;
  role: Role;
  lastViews: Listing[];
  wishlist: Listing[];
  pastBookings: Booking[];
}`, `6725455617070941000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Person.ts&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Address&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  street&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  city&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  state&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  zip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Profile&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  phone&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  address&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Address&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;enum&lt;/span&gt; Role &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  User &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;user&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;host&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  password&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Profile&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  role&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Role&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lastViews&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Listing&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  wishlist&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Listing&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  pastBookings&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Booking&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;53962229864720835000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Listing.ts

class GeoLocation {
  lat: number;
  lng: number;
}

class Listing {
  name: string;
  description: string;
  price: number;
  location: GeoLocation;
  host: Person;
}`, `53962229864720835000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Listing.ts&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;GeoLocation&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  lat&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lng&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Listing&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  description&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  price&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  location&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; GeoLocation&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Person&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;46499264253515340000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Booking.ts

class Booking {
  startDate: Date;
  endDate: Date;
  user: Person;
  host: Person;
  listing: Listing;
  total: number;
}`, `46499264253515340000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Booking.ts&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Booking&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  startDate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  endDate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  user&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Person&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Person&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  listing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Listing&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  total&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Take note that even though we wrote out &lt;strong&gt;Models&lt;/strong&gt; with &lt;strong&gt;Nested Schemas&lt;/strong&gt; but in reality, those relationships should be managed by &lt;code class=&quot;language-text&quot;&gt;reference&lt;/code&gt; (aka &lt;code class=&quot;language-text&quot;&gt;foreign key&lt;/code&gt;, aka &lt;code class=&quot;language-text&quot;&gt;IDs&lt;/code&gt;). To illustrate the point that data the consumers would get, we wrote it as &lt;strong&gt;nested&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;As you can see, if we do not &lt;code class=&quot;language-text&quot;&gt;transform&lt;/code&gt; our &lt;strong&gt;Domain Models&lt;/strong&gt; before returning to the consumers, we will then introduce &lt;strong&gt;circular dependencies&lt;/strong&gt; in the data shape that the consumers would get. And the response could get substantially large with all the deep circular nesting. Moreover, we also create some “security issue” (like &lt;code class=&quot;language-text&quot;&gt;password&lt;/code&gt;) by exposing the &lt;strong&gt;Domain Models&lt;/strong&gt; as they are: &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; etc… To address this issue without any tools, we might come up with something like this:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;89610957678349350000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// DTOs.ts

class ProfileDto {
  name: string;
  bio: string;
  phone: string;
  formattedAddress: string; // street + city + state + zip

  constructor(profile: Profile) {
    this.name = profile.name;
    this.bio = profile.bio;
    this.phone = profile.phone;
    this.formattedAddress = profile.address.street + profile.address.city + ...;/
  }
}

class PersonDto {
  email: string;
  role: Role;
  profile: ProfileDto;
  lastViews: ListingDto[];
  wishlist: ListingDto[];
  pastBookings: BookingDto[];

  constructor(person: Person) {
    this.email = person.email;
    this.role = person.role;
    this.profile = new ProfileDto(person.profile);
    this.lastViews = person.lastViews.map(lv =&gt; new ListingDto(lv));
    this.wishlist = person.wishlist.map(wl =&gt; new ListingDto(wl));
    this.pastBookings = person.pastBookings.map(pb =&gt; new BookingDto(pb));
  }
}

// to break the circular dependency here, we will then need to introduce another smaller Dto for Person

class PersonInfoDto {
  email: string;
  profile: ProfileDto;

  constructor(person: Person) {
    this.email = person.email;
    this.profile = new ProfileDto(person.profile);
  }
}

class ListingDto {
  name: string;
  description: string;
  host: PersonInfoDto;

  constructor(listing: Listing) {
    this.name = listing.name;
    this.description = listing.description;
    this.host = new PersonInfoDto(listing.host);
  }
}

class BookingDto {
  host: PersonInfoDto;
  listing: ListingDto;
  startDate: Date;
  endDate: Date;
  total: number;

  constructor(booking: Booking) {
    this.host = new PersonInfoDto(booking.host);
    this.listing = new ListingDto(booking.listing);
    this.startDate = booking.startDate;
    this.endDate = booking.endDate;
    this.total = booking.total;
  }
}`, `89610957678349350000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// DTOs.ts&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProfileDto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  bio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  phone&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  formattedAddress&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// street + city + state + zip&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Profile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; profile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; profile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phone &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; profile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phone&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;formattedAddress &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; profile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;street &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; profile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;city &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonDto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  role&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Role&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProfileDto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lastViews&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ListingDto&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  wishlist&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ListingDto&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  pastBookings&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BookingDto&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;person&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;role &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;role&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;profile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProfileDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastViews &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastViews&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;lv&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ListingDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lv&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wishlist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wishlist&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;wl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ListingDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;wl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pastBookings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pastBookings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;pb&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BookingDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pb&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// to break the circular dependency here, we will then need to introduce another smaller Dto for Person&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonInfoDto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  email&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  profile&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ProfileDto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;person&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Person&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;profile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ProfileDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;person&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ListingDto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  description&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PersonInfoDto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;listing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Listing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; listing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; listing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonInfoDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;listing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BookingDto&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PersonInfoDto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  listing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ListingDto&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  startDate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  endDate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Date&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  total&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;booking&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Booking&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;host &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonInfoDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;booking&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;listing &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ListingDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;booking&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;listing&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; booking&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;startDate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;endDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; booking&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;endDate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;total &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; booking&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;total&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;DTOs&lt;/strong&gt; are very specific and will differ from project to project. Decision making process for this dumbed-down version of this particular use-case:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;For &lt;code class=&quot;language-text&quot;&gt;Profile.address&lt;/code&gt;, we only want to display a &lt;code class=&quot;language-text&quot;&gt;formattedAddress&lt;/code&gt; string.&lt;/li&gt;
&lt;li&gt;For &lt;code class=&quot;language-text&quot;&gt;Person.lastViews&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Person.wishlist&lt;/code&gt;, we would normally display like a list of cards with some minimal information. That’s why &lt;code class=&quot;language-text&quot;&gt;ListingDto&lt;/code&gt; contains those information.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, you might have noticed the &lt;code class=&quot;language-text&quot;&gt;constructor()&lt;/code&gt; in each &lt;strong&gt;DTOs&lt;/strong&gt;, we are essentially “map” the &lt;strong&gt;Domain Models&lt;/strong&gt; to these &lt;strong&gt;DTOs&lt;/strong&gt; manually by passing in the appropriate &lt;strong&gt;Domain Model&lt;/strong&gt; in the &lt;code class=&quot;language-text&quot;&gt;constructor()&lt;/code&gt; of a matching &lt;strong&gt;DTO&lt;/strong&gt;. This approach is safe and it works well. In fact, our company uses this &lt;em&gt;hand-written&lt;/em&gt; approach in one of our
&lt;a href=&quot;https://nestjs.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;NestJS&lt;/a&gt; backend. However, this approach is not a good solution because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Violates &lt;strong&gt;DRY&lt;/strong&gt;. In a real scenario, you’d end up with many &lt;strong&gt;DTOs&lt;/strong&gt; matching against a single &lt;strong&gt;Domain Model&lt;/strong&gt;. The mapping is almost never &lt;em&gt;one-model-one-view-model&lt;/em&gt; and you probably have to re-type a lot of mapping, both simple and complex ones.&lt;/li&gt;
&lt;li&gt;Error-prone. Because of the amount of re-typing, your code is more prone to human-errors.&lt;/li&gt;
&lt;li&gt;One-way mapping. Without introducing even more code, you cannot have two-ways mapping &lt;code class=&quot;language-text&quot;&gt;Domain &amp;lt;=&amp;gt; DTO&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Separation of Concern. Now this is a debatable one. One could argue that the mapping logic can (and should) stay within the &lt;strong&gt;DTO&lt;/strong&gt; because that is where the transformation should occur. But, I’d try to make my &lt;strong&gt;DTO&lt;/strong&gt; as clean and slim as possible by separating the Mapping logic out of the &lt;strong&gt;DTO&lt;/strong&gt; itself.&lt;/li&gt;
&lt;/ol&gt;
&lt;iframe
     src=&quot;https://codesandbox.io/embed/pedantic-tdd-c3ct1?fontsize=12&amp;theme=dark&quot;
     style=&quot;width:100%; height:500px; border:0; border-radius: 4px; overflow:hidden;&quot;
     title=&quot;pedantic-tdd-c3ct1&quot;
     allow=&quot;geolocation; microphone; camera; midi; vr; accelerometer; gyroscope; payment; ambient-light-sensor; encrypted-media; usb&quot;
     sandbox=&quot;allow-modals allow-forms allow-popups allow-scripts allow-same-origin&quot;
  &gt;&lt;/iframe&gt;
&lt;h2 id=&quot;automapper-can-help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#automapper-can-help&quot; aria-label=&quot;automapper can help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;AutoMapper can help&lt;/h2&gt;
&lt;p&gt;Let me recap, &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; implementation of &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is an &lt;em&gt;Object to Object mapping solution by convention&lt;/em&gt;. Before we get to how &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; can help us, allow me to introduce to all of you that are not familiar with &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; some terminologies so you can follow better:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt;: This is the main object that will help with the mapping. Usually in an &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; implementation, &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; is exposed as a singleton. In &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt;, there’s a singleton &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt;. However, you can always instantiate another &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; if you wish to manage your &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; instance.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt;: A &lt;code class=&quot;language-text&quot;&gt;Domain Model&lt;/code&gt; can have at least 1 &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt;. A &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; is a class that extends &lt;code class=&quot;language-text&quot;&gt;MappingProfileBase&lt;/code&gt; and it represents a profile of &lt;strong&gt;ONE Domain Models&lt;/strong&gt; and its matching &lt;strong&gt;DTOs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Mapping&lt;/code&gt;: A &lt;code class=&quot;language-text&quot;&gt;Mapping&lt;/code&gt; is a blueprint between two &lt;strong&gt;Models&lt;/strong&gt;, usually a &lt;strong&gt;Domain Model&lt;/strong&gt; and a &lt;strong&gt;DTO&lt;/strong&gt;. The &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; can only proceed with the &lt;strong&gt;map&lt;/strong&gt; operation if the &lt;code class=&quot;language-text&quot;&gt;Mapping&lt;/code&gt; exists.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now, let’s start with the &lt;strong&gt;issues&lt;/strong&gt; one by one, not in any particular order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Separation of Concern&lt;/strong&gt;
As the definition of &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; has stated, a &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; can house all the mapping logics for a specific &lt;strong&gt;Domain Model&lt;/strong&gt;. We have 3 &lt;strong&gt;Domain Models&lt;/strong&gt; so we’ll have 3 &lt;strong&gt;Profiles&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;33335851411350626000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class PersonProfile extends MappingProfileBase {
  constructor() {
    super(); // needed for this.profileName
  }

  configure(mapper: AutoMapper): void {
    throw new Error(&amp;quot;Method not implemented.&amp;quot;);
  }
}

class ListingProfile extends MappingProfileBase {
  constructor() {
    super();
  }

  configure(mapper: AutoMapper): void {
    throw new Error(&amp;quot;Method not implemented.&amp;quot;);
  }
}

class BookingProfile extends MappingProfileBase {
  constructor() {
    super();
  }

  configure(mapper: AutoMapper): void {
    throw new Error(&amp;quot;Method not implemented.&amp;quot;);
  }
}`, `33335851411350626000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonProfile&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MappingProfileBase&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// needed for this.profileName&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AutoMapper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Method not implemented.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ListingProfile&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MappingProfileBase&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AutoMapper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Method not implemented.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BookingProfile&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MappingProfileBase&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AutoMapper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Method not implemented.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s implement our &lt;code class=&quot;language-text&quot;&gt;PersonProfile.configure()&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;68080929169916800000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class PersonProfile extends MappingProfileBase {
  constructor() {
    super(); // needed for this.profileName
  }

  configure(mapper: AutoMapper): void {
    mapper
      .createMap(Profile, ProfileDto) // create the Mapping for Profile -&gt; ProfileDto
      .forMember(
        d =&gt; d.name,
        opts =&gt; opts.mapFrom(s =&gt; s.firstName + &amp;quot; &amp;quot; + s.lastName)
      ) // map from Profile.firstName and Profile.lastName to ProfileDto.name. TypeScript will help out here
      .forMember(
        d =&gt; d.formattedAddress,
        opts =&gt;
          opts.mapFrom(
            s =&gt; s.address.street + &amp;quot; &amp;quot; + s.address.city + &amp;quot; &amp;quot; + s.address.state
          )
      ) // d stands for destination, s stands for source
      .reverseMap(); // create the Mapping for ProfileDto -&gt; Profile

    mapper.createMap(Person, PersonDto).reverseMap(); // create the Mapping for Person -&gt; PersonDto and PersonDto -&gt; Person
  }
}`, `68080929169916800000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PersonProfile&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MappingProfileBase&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// needed for this.profileName&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AutoMapper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    mapper
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Profile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ProfileDto&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// create the Mapping for Profile -&gt; ProfileDto&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// map from Profile.firstName and Profile.lastName to ProfileDto.name. TypeScript will help out here&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forMember&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;formattedAddress&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token parameter&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
          opts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mapFrom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token parameter&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;street &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;city &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;address&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state
          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// d stands for destination, s stands for source&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reverseMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// create the Mapping for ProfileDto -&gt; Profile&lt;/span&gt;

    mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Person&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PersonDto&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reverseMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// create the Mapping for Person -&gt; PersonDto and PersonDto -&gt; Person&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, we say &lt;code class=&quot;language-text&quot;&gt;PersonProfile extends MappingProfileBase&lt;/code&gt; to initiate our contract between &lt;code class=&quot;language-text&quot;&gt;PersonProfile&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;MappingProfileBase&lt;/code&gt; which is used internally by &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt;. The &lt;code class=&quot;language-text&quot;&gt;constructor&lt;/code&gt; is needed to grab &lt;code class=&quot;language-text&quot;&gt;PersonProfile&lt;/code&gt; string and assign it to &lt;code class=&quot;language-text&quot;&gt;this.profileName&lt;/code&gt;. Each instance of &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; will keep track of its &lt;code class=&quot;language-text&quot;&gt;profiles&lt;/code&gt; by &lt;code class=&quot;language-text&quot;&gt;profileName&lt;/code&gt;. Then we implement &lt;code class=&quot;language-text&quot;&gt;configure()&lt;/code&gt; method which receives the &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; instance. Next, we proceed to start creating our first mappings by calling &lt;code class=&quot;language-text&quot;&gt;createMap()&lt;/code&gt; method which follows &lt;a href=&quot;https://en.wikipedia.org/wiki/Fluent_interface&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Fluent Interface&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;createMap(Profile, ProfileDto)&lt;/code&gt;: this creates the Mapping for &lt;code class=&quot;language-text&quot;&gt;Profile -&amp;gt; ProfileDto&lt;/code&gt;. This method also establishes mapping configurations for properties that are on both &lt;code class=&quot;language-text&quot;&gt;Profile&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;ProfileDto&lt;/code&gt;. Remember, &lt;strong&gt;by convention&lt;/strong&gt;? So, &lt;code class=&quot;language-text&quot;&gt;Profile.bio&lt;/code&gt; will be mapped to &lt;code class=&quot;language-text&quot;&gt;ProfileDto.bio&lt;/code&gt; without you having to configure that.&lt;/li&gt;
&lt;li&gt;What if we need to configure a property on the &lt;strong&gt;Destination&lt;/strong&gt; (&lt;code class=&quot;language-text&quot;&gt;ProfileDto&lt;/code&gt; in this case)? &lt;code class=&quot;language-text&quot;&gt;forMember()&lt;/code&gt; is created for that purpose. Pass in a &lt;strong&gt;Selector Function&lt;/strong&gt; to let &lt;code class=&quot;language-text&quot;&gt;Mapper&lt;/code&gt; know which property you want to configure explicitly and another function that receives the &lt;code class=&quot;language-text&quot;&gt;ForMemberOptions&lt;/code&gt; object which exposes different methods for you to configure the property being selected. Here, we want to configure &lt;code class=&quot;language-text&quot;&gt;ProfileDto.name&lt;/code&gt; explicitly and we want to take &lt;code class=&quot;language-text&quot;&gt;Profile.firstName&lt;/code&gt; value and &lt;code class=&quot;language-text&quot;&gt;Profile.lastName&lt;/code&gt; value to assign to &lt;code class=&quot;language-text&quot;&gt;ProfileDto.name&lt;/code&gt;. Therefore, we use &lt;code class=&quot;language-text&quot;&gt;mapFrom()&lt;/code&gt; which takes in yet another &lt;strong&gt;Selector Function&lt;/strong&gt; to get the value for &lt;code class=&quot;language-text&quot;&gt;ProfileDto.name&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; will help out here with safe-typings. You will actually get an error if you’re trying to map a value that is different than a &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;ProfileDto.name&lt;/code&gt; (which is a &lt;code class=&quot;language-text&quot;&gt;string&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;https://p30.f1.n0.cdn.getcloudapp.com/items/NQueGbZ7/Image+2019-11-17+at+1.15.23+AM.png?v=590d3ef8d8db3eaec645c56e74ae0fa8&quot; alt=&quot;Error&quot;&gt;
&lt;em&gt;TypeError when trying to map unmatched value type&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; follows as close to the original .NET AutoMapper API as possible.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;We repeat the process for &lt;code class=&quot;language-text&quot;&gt;formattedAddress&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Call &lt;code class=&quot;language-text&quot;&gt;reverseMap()&lt;/code&gt; to create another Mapping for &lt;code class=&quot;language-text&quot;&gt;ProfileDto -&amp;gt; Profile&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Create another Mapping for &lt;code class=&quot;language-text&quot;&gt;Person -&amp;gt; PersonDto&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Call &lt;code class=&quot;language-text&quot;&gt;reverseMap()&lt;/code&gt; to create another Mapping for &lt;code class=&quot;language-text&quot;&gt;PersonDto -&amp;gt; Person&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Why is &lt;code class=&quot;language-text&quot;&gt;createMap(Person, PersonDto)&lt;/code&gt; so short/empty?&lt;/strong&gt; Again, remember &lt;strong&gt;by convention&lt;/strong&gt;? This is one of the strong point of an &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; will try to map matching properties on both &lt;code class=&quot;language-text&quot;&gt;Person&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;PersonDto&lt;/code&gt; for primitives, nested models and list. Here, we set &lt;code class=&quot;language-text&quot;&gt;PersonDto.profile&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;ProfileDto&lt;/code&gt; and we have already setup a Mapping for &lt;code class=&quot;language-text&quot;&gt;Profile -&amp;gt; ProfileDto&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; will be able to map from &lt;code class=&quot;language-text&quot;&gt;Person.profile&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;PersonDto.profile&lt;/code&gt; without any configuration because &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; will get the existing Mapping for &lt;code class=&quot;language-text&quot;&gt;Profile -&amp;gt; ProfileDto&lt;/code&gt; to map &lt;code class=&quot;language-text&quot;&gt;profile&lt;/code&gt; since a Mapping for any pair of &lt;strong&gt;Models&lt;/strong&gt; is unique. &lt;/p&gt;
&lt;p&gt;The same goes for &lt;code class=&quot;language-text&quot;&gt;Listing&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Booking&lt;/code&gt; so to simplify, I will not be putting code for those in this blog. You can find a full example here: &lt;a href=&quot;https://codesandbox.io/s/pedantic-tdd-c3ct1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;CodeSandbox&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; currently supports a wide range of features:&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Basic Mapping between two classes&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Basic Mapping for nested classes&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Array/List Mapping&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Flattening&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; ReverseMap&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Value Converters&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Value Resolvers&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Async&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Before/After Callback&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Naming Conventions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;so please check out &lt;a href=&quot;https://github.com/nartc/mapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;h2 id=&quot;flaws&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#flaws&quot; aria-label=&quot;flaws permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Flaws&lt;/h2&gt;
&lt;p&gt;Just want to get it out there, I work on this library knowing the limitations of &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; on its &lt;code class=&quot;language-text&quot;&gt;reflection&lt;/code&gt; capabilities. Hence, there are some flaws that are worth mentioning:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Selector Function&lt;/strong&gt;: Currently, the way I grab the properties from these &lt;strong&gt;Selector Function&lt;/strong&gt; is kind of flaky. I expect bugs in different scenarios when the library is used more. Even though I am pretty confident since I have unit test for &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reflection&lt;/strong&gt;: &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; has a peer dependency on &lt;code class=&quot;language-text&quot;&gt;reflect-metadata&lt;/code&gt; and two dependencies which are &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;lodash.set&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;lodash.set&lt;/code&gt; is pretty self-explanatory. So I will explain the other two:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;reflect-metadata&lt;/strong&gt;: This is used to be able to get metadata from decorators.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;class-transformer&lt;/strong&gt;: This library exposes a couple of nifty stuffs that &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; can make use of. Namely, &lt;code class=&quot;language-text&quot;&gt;plainToClass()&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;@Expose()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;@Type()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;I have written about this in the previous blog on &lt;a href=&quot;/blogs/automapper-typescript&quot;&gt;Why I (want to) build an AutoMapper in TypeScript?&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And to fix and/or improve flaws, I need more trials and more flaws. Please, if it fits your use-case, give &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; a try. &lt;/p&gt;
&lt;h2 id=&quot;integration&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#integration&quot; aria-label=&quot;integration permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Integration&lt;/h2&gt;
&lt;p&gt;Beside the core library &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt;, I have also written a wrapper to be used in &lt;code class=&quot;language-text&quot;&gt;NestJS&lt;/code&gt; which goes by &lt;code class=&quot;language-text&quot;&gt;nestjsx-automapper&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt;. It is a part of &lt;code class=&quot;language-text&quot;&gt;NestJSX&lt;/code&gt; opinionated set of modules written specifically for &lt;code class=&quot;language-text&quot;&gt;NestJS&lt;/code&gt;. Check it out on &lt;a href=&quot;https://github.com/nestjsx/automapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;future&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#future&quot; aria-label=&quot;future permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Future&lt;/h2&gt;
&lt;p&gt;Currently, &lt;code class=&quot;language-text&quot;&gt;@nartc/automapper&lt;/code&gt; is waiting for more feedbacks and issues so it can be improved upon. Tutorial wise, I plan to record a video tutorial beside this blog post so stay tune for that. It feels much nicer on video, I promise. That said, if you decide to give the library a try, keep the feedbacks/issues coming. TIA!&lt;/p&gt;
&lt;h2 id=&quot;credits&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#credits&quot; aria-label=&quot;credits permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Credits&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://automapper.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;.NET AutoMapper&lt;/a&gt; for the inspiration&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/loedeman/AutoMapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;automapper-ts&lt;/a&gt; for the starting point&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cleancode.blog/an-automapper-for-php-the-powerful-and-simple-solution-for-mappings/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Cleancode blog&lt;/a&gt; for the cover and for some ideas behind putting this blog together.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thank you for reading. I’m looking forward to seeing you in the next blog 🚀&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why I (want to) build an AutoMapper in TypeScript?]]></title><description><![CDATA[Hey, it’s been around a month since my last blog post 😢. Work has been pretty busy lately for me. Talk about work, this week marks my…]]></description><link>https://nartc.netlify.com/blogs/automapper-typescript/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/automapper-typescript/</guid><pubDate>Wed, 16 Oct 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hey, it’s been around a month since my last blog post 😢. Work has been pretty busy lately for me. Talk about work, this week marks my 2 years as a &lt;strong&gt;Developer&lt;/strong&gt; at &lt;a href=&quot;http://architectnow.net&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;ArchitectNow&lt;/a&gt;. Over the course of 2 years, I’ve learned so many cool technologies like: &lt;code class=&quot;language-text&quot;&gt;.NET Core&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Swagger/OpenAPI&lt;/code&gt; and especially &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/da56c142027d2f9b254f7944648a1afb/38ece/automapper-csharp.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAALABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAMF/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEAMQAAABzUhRMf/EABgQAAIDAAAAAAAAAAAAAAAAAAAhAREg/9oACAEBAAEFAkVAsf/EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8BP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABcQAAMBAAAAAAAAAAAAAAAAAAAgMjH/2gAIAQEABj8Coo1P/8QAGRABAAIDAAAAAAAAAAAAAAAAAQBRIEGB/9oACAEBAAE/IUogmhEF+Yf/2gAMAwEAAgADAAAAEHPP/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPxA//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGRABAAMBAQAAAAAAAAAAAAAAAQARUSBh/9oACAEBAAE/EBCiuAwC12IxCgehcf/Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;automapper-csharp&quot;
        title=&quot;automapper-csharp&quot;
        src=&quot;/static/da56c142027d2f9b254f7944648a1afb/bbe0c/automapper-csharp.jpg&quot;
        srcset=&quot;/static/da56c142027d2f9b254f7944648a1afb/f7be0/automapper-csharp.jpg 160w,
/static/da56c142027d2f9b254f7944648a1afb/b4845/automapper-csharp.jpg 320w,
/static/da56c142027d2f9b254f7944648a1afb/bbe0c/automapper-csharp.jpg 640w,
/static/da56c142027d2f9b254f7944648a1afb/18e3b/automapper-csharp.jpg 960w,
/static/da56c142027d2f9b254f7944648a1afb/38ece/automapper-csharp.jpg 1280w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Original .NET AutoMapper&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is “A convention-based object-object mapper. 100% organic and gluten-free. Takes out all of the fuss of mapping one object to another.” created by &lt;strong&gt;Jimmy Bogard&lt;/strong&gt; (&lt;a href=&quot;https://github.com/AutoMapper/AutoMapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;). It’s a pretty simple description of what &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is, ain’t it? Well, it does a lot for you. And it’s an awesome tool given the very high capability of &lt;a href=&quot;https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Reflection&lt;/a&gt; in &lt;code class=&quot;language-text&quot;&gt;C#&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;but-why-automapper&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#but-why-automapper&quot; aria-label=&quot;but why automapper permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;But why AutoMapper?&lt;/h2&gt;
&lt;p&gt;tldr; &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is a tool that provides &lt;code class=&quot;language-text&quot;&gt;Object Mapping&lt;/code&gt; by &lt;strong&gt;convention&lt;/strong&gt;. If you construct your &lt;code class=&quot;language-text&quot;&gt;View Models&lt;/code&gt; consistently with your &lt;code class=&quot;language-text&quot;&gt;Domain Models&lt;/code&gt;, then you have established a &lt;strong&gt;convention&lt;/strong&gt; and &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is a great tool for situations like this. It will take away all the &lt;em&gt;boring&lt;/em&gt; mapping. You can read the whole blog post here: &lt;a href=&quot;https://jimmybogard.com/automappers-design-philosophy/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Automappers Design Philosophy&lt;/a&gt;. I’ll quote the last part of the blog here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AutoMapper works because it enforces a convention. It assumes that your destination types are a subset of the source type. It assumes that everything on your destination type is meant to be mapped. It assumes that the destination member names follow the exact name of the source type. It assumes that you want to flatten complex models into simple ones.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;All of these assumptions come from our original use case - view models for MVC, where all of those assumptions are in line with our view model design. With AutoMapper, we could enforce our view model design philosophy. This is the true power of conventions - laying down a set of enforceable design rules that help you streamline development along the way.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;By enforcing conventions, we let our developers focus on the value add activities, and less on the activities that provided zero or negative value, like designing bespoke view models or writing a thousand dumb unit tests.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;And this is why our usage of AutoMapper has stayed so steady over the years - because our design philosophy for view models hasn’t changed. If you find yourself hating a tool, it’s important to ask - for what problems was this tool designed to solve? And if those problems are different than yours, perhaps that tool isn’t a good fit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;automapper-is-not-that-well-known-and-hated&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#automapper-is-not-that-well-known-and-hated&quot; aria-label=&quot;automapper is not that well known and hated permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;AutoMapper is not &lt;em&gt;that&lt;/em&gt; well-known, and &lt;em&gt;hated&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;I know of &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; through work and I was (still am) very impressed with how convenient &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is. But I’m a tad surprised when no one really knows what &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is when I ask around. If people don’t really know what &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is, it kind of defeats my purpose of creating it in &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; and will be really hard to promote it 😅. This &lt;a href=&quot;https://www.reddit.com/r/javascript/comments/4tg69t/question_typescript_auto_mapping/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Reddit post&lt;/a&gt; also discusses about whether you want to use &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; in your project. There is also a plethora of blog posts about &lt;em&gt;“Why No AutoMapper?”&lt;/em&gt; (I was googling for &lt;em&gt;Why AutoMapper?&lt;/em&gt; 😅). Here’s one of them (and it’s a good blog post to be honest with you) &lt;a href=&quot;https://cezarypiatek.github.io/post/why-i-dont-use-automapper/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Why I Don’t Use AutoMapper&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;but-i-still-want-to-use-automapper-in-typescript&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#but-i-still-want-to-use-automapper-in-typescript&quot; aria-label=&quot;but i still want to use automapper in typescript permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;But I still want to use AutoMapper in TypeScript&lt;/h2&gt;
&lt;p&gt;Like I mentioned above (and also in some of the blog posts), &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; in the &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; world isn’t really a thing because of how limited the &lt;code class=&quot;language-text&quot;&gt;Reflection Capability&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; is. It is not as good as &lt;code class=&quot;language-text&quot;&gt;C#&lt;/code&gt; because in the end, &lt;code class=&quot;language-text&quot;&gt;TS&lt;/code&gt; is compiled down to a dynamic language, &lt;code class=&quot;language-text&quot;&gt;JS&lt;/code&gt;, anyway. &lt;/p&gt;
&lt;p&gt;Let me dial back to why we use &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; at work in the first place. At &lt;strong&gt;ArchitectNow&lt;/strong&gt;, we utilize &lt;code class=&quot;language-text&quot;&gt;Swagger/OpenAPI&lt;/code&gt; heavily to document our APIs, and combined with tools like &lt;code class=&quot;language-text&quot;&gt;NSwag&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;swagger-codegen&lt;/code&gt;, we have an automation pipeline to generate &lt;code class=&quot;language-text&quot;&gt;HTTP calls&lt;/code&gt; for client-side applications: a web app or a mobile app. Basically, we have our &lt;code class=&quot;language-text&quot;&gt;Domain Models&lt;/code&gt; which are the shape of data that will go in the &lt;code class=&quot;language-text&quot;&gt;Persistence Layer&lt;/code&gt; (Database) of the application. On one hand, we also have &lt;em&gt;conventionally matching&lt;/em&gt; &lt;code class=&quot;language-text&quot;&gt;View Models&lt;/code&gt; that will be exposed to be used by the Clients via &lt;code class=&quot;language-text&quot;&gt;Controllers&lt;/code&gt; (API Endpoints). Without &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;, we would have to “manually” map a lot of data back and forth on every single API calls. Everything’s good on the &lt;code class=&quot;language-text&quot;&gt;C#&lt;/code&gt; side of things, because we have &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On the &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; side, we take a big interest in &lt;code class=&quot;language-text&quot;&gt;NestJS&lt;/code&gt;. If you don’t know what &lt;code class=&quot;language-text&quot;&gt;NestJS&lt;/code&gt; is, you can learn about it &lt;a href=&quot;https://nestjs.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;here&lt;/a&gt;. tldr; &lt;code class=&quot;language-text&quot;&gt;NestJS&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; framework that takes on &lt;em&gt;Angular-like&lt;/em&gt; architecture which helps with building maintainable and scalable server-side applications. When building &lt;code class=&quot;language-text&quot;&gt;NestJS&lt;/code&gt; applications, we use the same approach as we build a &lt;code class=&quot;language-text&quot;&gt;.NET Core&lt;/code&gt; application. &lt;code class=&quot;language-text&quot;&gt;Domain Models&lt;/code&gt; &amp;#x3C;=&gt; &lt;code class=&quot;language-text&quot;&gt;View Models&lt;/code&gt;. Unfortunately, there isn’t a “good enough” &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; library in the &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt; world. There are some worth mentioning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/loedeman/AutoMapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;automapper-ts&lt;/a&gt;  by Bert Loedeman - This is the closest, in terms of syntax, to the original &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Wufe/mapper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;@wufe/mapper&lt;/a&gt; by Simone Bembi - This is also a very nice library. &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nobrainr/morphism&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;morphism&lt;/a&gt; by Yann RENAUDIN - This is an interesting library. Not really &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; but it might do the job.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;…but all of them have some problems, for me. &lt;code class=&quot;language-text&quot;&gt;automapper-ts&lt;/code&gt; is a bit outdated and doesn’t seem to be actively maintained. &lt;code class=&quot;language-text&quot;&gt;@wufe/mapper&lt;/code&gt; is also great but doesn’t support as much as I like it to and it might be hard/long for features that I might want/look for in an &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; tool to be supported. Last but not least, &lt;code class=&quot;language-text&quot;&gt;morphism&lt;/code&gt; is something that comes up in my search and it looks super interesting, its syntax does not adhere to &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; syntax however.&lt;/p&gt;
&lt;p&gt;With all of these in mind, I’ve decided to take a stab at creating my own &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;TypeScript&lt;/code&gt;, mainly inspired by &lt;code class=&quot;language-text&quot;&gt;automapper-ts&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;problems-with-typescript&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#problems-with-typescript&quot; aria-label=&quot;problems with typescript permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Problems with TypeScript&lt;/h2&gt;
&lt;p&gt;Again, &lt;code class=&quot;language-text&quot;&gt;Reflection&lt;/code&gt; is a big part in trying to solve the &lt;strong&gt;auto&lt;/strong&gt; part of &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;. Let’s look at one example:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;92883183928339170000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class User {
  firstName: string;
  lastName: string;
}`, `92883183928339170000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;the above &lt;code class=&quot;language-text&quot;&gt;.ts&lt;/code&gt; block will be compiled to &lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;2818733056879874000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class User {}

// or in older ES
function User() {}`, `2818733056879874000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// or in older ES&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So now when you try to instantiate a &lt;code class=&quot;language-text&quot;&gt;new User()&lt;/code&gt; by writing the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;28433213473540153000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const user = new User();
console.log(user);

// User { firstName: undefined, lastName: undefined }; at least this was my expectation

// but in reality, you&apos;ll get: User {}`, `28433213473540153000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// User { firstName: undefined, lastName: undefined }; at least this was my expectation&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// but in reality, you&apos;ll get: User {}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Uh…where’s my &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt;? Let’s look at another code block before I explain why &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt; are important:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;79275542958470710000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// SomeFileName.cs

// Same Domain model as in TypeScript
class User {
    public string FirstName {get; set;}
    public string LastName {get; set;}
    // ... some additional properties ...
}

// Some ViewModel class
class UserVm {
    public string FirstName {get; set;}
    public string LastName {get; set;}
    // ... some additional properties ...
}

...
// Create the Mapping between User and UserVm
CreateMap&lt;User, UserVm&gt;();
...

...
// Actual map from User to UserVm
var userVm = Mapper.Map&lt;UserVm&gt;(user);
...`, `79275542958470710000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;csharp&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-csharp line-numbers&quot;&gt;&lt;code class=&quot;language-csharp&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// SomeFileName.cs&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Same Domain model as in TypeScript&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; FirstName &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; LastName &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ... some additional properties ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Some ViewModel class&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserVm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; FirstName &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token return-type class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;string&lt;/span&gt;&lt;/span&gt; LastName &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ... some additional properties ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token range operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Create the Mapping between User and UserVm&lt;/span&gt;
&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;CreateMap&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; UserVm&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token range operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;token range operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Actual map from User to UserVm&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt;&lt;/span&gt; userVm &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Mapper&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token generic-method&quot;&gt;&lt;span class=&quot;token function&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;token generic class-name&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;UserVm&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token range operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the &lt;code class=&quot;language-text&quot;&gt;C#&lt;/code&gt; world,  &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; will be able to map &lt;code class=&quot;language-text&quot;&gt;User.FirstName&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;UserVm.FirstName&lt;/code&gt; because of &lt;strong&gt;Convention&lt;/strong&gt;. They share the same property name &lt;code class=&quot;language-text&quot;&gt;FirstName&lt;/code&gt;. On the contrary in &lt;code class=&quot;language-text&quot;&gt;TS&lt;/code&gt;, you cannot do that without having to do a bit more work. The &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; instance in &lt;code class=&quot;language-text&quot;&gt;TS&lt;/code&gt; doesn’t contain any &lt;code class=&quot;language-text&quot;&gt;properties&lt;/code&gt; because we never &lt;strong&gt;actually declared&lt;/strong&gt; them in our &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; class. Remember what I said about &lt;code class=&quot;language-text&quot;&gt;Typings&lt;/code&gt; will NOT be persisted earlier, this is exactly that problem.&lt;/p&gt;
&lt;p&gt;You can &lt;em&gt;kinda&lt;/em&gt; fix the problem by writing the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;41356696547013730000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class User {
  constructor(public firstName: string, public lastName: string) {}
}`, `41356696547013730000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; firstName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; lastName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, the compiled &lt;code class=&quot;language-text&quot;&gt;JS&lt;/code&gt; code will look something like:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;35833087328792003000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`class User {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}`, `35833087328792003000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;firstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lastName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; firstName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lastName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; lastName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can see that we now &lt;strong&gt;actually declared&lt;/strong&gt; &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;this&lt;/code&gt; instance when we &lt;code class=&quot;language-text&quot;&gt;new()&lt;/code&gt; up one. Hence, when you do the following:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;11074025540704002000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const user = new User();
console.log(user);
// logs User {firstName: undefined, lastName: undefined};`, `11074025540704002000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// logs User {firstName: undefined, lastName: undefined};&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great! I have &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt; in my &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; instance. But why are those important? Because we have to &lt;code class=&quot;language-text&quot;&gt;auto-map&lt;/code&gt; them. Technically with &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt;, you never really do a map manually by: &lt;code class=&quot;language-text&quot;&gt;userVm.firstName = user.firstName&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; is supposed to do that for you. What we can do to help &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; (actually, we &lt;strong&gt;need&lt;/strong&gt; to) is to &lt;code class=&quot;language-text&quot;&gt;create a Mapping between a Source and a Destination&lt;/code&gt; (&lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; as Source and &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt; as Destination in this case).&lt;/p&gt;
&lt;p&gt;I expect my &lt;code class=&quot;language-text&quot;&gt;automapper&lt;/code&gt; to do the following when it starts mapping &lt;code class=&quot;language-text&quot;&gt;User -&amp;gt; UserVm&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create a new instance of &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt; (1)&lt;/li&gt;
&lt;li&gt;Loop through the &lt;code class=&quot;language-text&quot;&gt;keys&lt;/code&gt; on (1)&lt;/li&gt;
&lt;li&gt;Grab the value for the same key on &lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt; object passed in.&lt;/li&gt;
&lt;li&gt;Assign the “found” value on (1)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Something like this in code:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;1532903283319231200&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const destination = new UserVm();

for (const key in Object.keys(destination)) {
  // do some null check for source[key]
  // if key exists on source, then
  destination[key] = source[key]
}

return destination;`, `1532903283319231200`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; destination &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserVm&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; key &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// do some null check for source[key]&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// if key exists on source, then&lt;/span&gt;
  destination&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; source&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; destination&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Without &lt;code class=&quot;language-text&quot;&gt;firstName&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;lastName&lt;/code&gt; being “visible” on a new instance of &lt;code class=&quot;language-text&quot;&gt;UserVm&lt;/code&gt;, it is impossible to map in this case because &lt;code class=&quot;language-text&quot;&gt;Object.keys(destination)&lt;/code&gt; will return an empty &lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;. There was no key on &lt;code class=&quot;language-text&quot;&gt;destination&lt;/code&gt;. The &lt;code class=&quot;language-text&quot;&gt;short-hand&lt;/code&gt; syntax to declare class properties inside of &lt;code class=&quot;language-text&quot;&gt;constructor&lt;/code&gt; was my first iteration of the library. Shortly after, I tried to utilize &lt;code class=&quot;language-text&quot;&gt;reflect-metadata&lt;/code&gt; to declare the properties on the &lt;code class=&quot;language-text&quot;&gt;class&lt;/code&gt; “automatically”. However, I kinda ran into the same problem which was no properties was there in the first place to grab. &lt;code class=&quot;language-text&quot;&gt;Class Decorator&lt;/code&gt; does not provide any information about its property and &lt;code class=&quot;language-text&quot;&gt;Property Decorator&lt;/code&gt; is kind of verbose but &lt;code class=&quot;language-text&quot;&gt;Property Decorator&lt;/code&gt; is like my only answer to this at the moment. Talk about &lt;code class=&quot;language-text&quot;&gt;Property Decorator&lt;/code&gt;, I suddenly remembered a library that kind of has that already, which is &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt;. I turn to &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt; for not having to reinvent the wheel (well, for being lazy 😅). This library provides three things that I need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@Expose&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;@Type&lt;/code&gt; decorators. &lt;code class=&quot;language-text&quot;&gt;@Expose&lt;/code&gt; solves the problem with a property being visible on a new instance. &lt;code class=&quot;language-text&quot;&gt;@Type&lt;/code&gt; solves the same problem, but with nested model.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;plainToClass()&lt;/code&gt; method. &lt;code class=&quot;language-text&quot;&gt;plainToClass&lt;/code&gt; works in sync with &lt;code class=&quot;language-text&quot;&gt;Expose&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Type&lt;/code&gt; to give you an instance with all of its properties “exposed” to be able to map.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hence, I’ve decided to include &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt; as one of my library’s dependency. Well, before you judge me, I did try to build &lt;code class=&quot;language-text&quot;&gt;Expose&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Type&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;plainToClass&lt;/code&gt; by myself using &lt;code class=&quot;language-text&quot;&gt;reflect-metadata&lt;/code&gt;. However, the difference in bundle size between including &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt; vs a half-baked internal implementation is &lt;strong&gt;0.3kb&lt;/strong&gt;. Not really worth it NOT to include &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt;. Plus, &lt;code class=&quot;language-text&quot;&gt;class-transformer&lt;/code&gt; provides a lot more than my implementation.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There are a lot more problems that I’ve faced and am still facing while trying to build this &lt;strong&gt;first&lt;/strong&gt; library. Namely, they are features that the original &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; supports like: &lt;code class=&quot;language-text&quot;&gt;Reverse Mapping&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Type Converters&lt;/code&gt; etc… which I will go through each one in more detail in the next blog. I also face problem with getting a value on an object with a path which I turn to &lt;code class=&quot;language-text&quot;&gt;lodash.get&lt;/code&gt; (because I’m lazy to implement it and I probably won’t implement it to cover enough cases like &lt;code class=&quot;language-text&quot;&gt;Lodash&lt;/code&gt; does aka best excuse ever!). Keeping the syntax as close to &lt;code class=&quot;language-text&quot;&gt;AutoMapper&lt;/code&gt; as possible is also a pain point, Fluent API 💪. In the end, I am proud of myself for doing what I’m doing. Trust me, you’re going to learn so much when you try to build a library, or a solution to your problem in general. Sharing my thoughts and my work with others is such a great way to reflect on what I’ve been doing and it brings me such joy to share my findings and knowledge with everybody out there. Thank you for reading and I’ll see you in the next one which is going to be: &lt;strong&gt;AutoMapper TypeScript in Action&lt;/strong&gt; (Link coming up). Finally, my library is actually live and is on &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt;, you can check the Github repo out &lt;a href=&quot;https://github.com/nartc/automapper-nartc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;here&lt;/a&gt;. Please feel free to try it out, look through the source and leave me ANY feedbacks in the Issues section, I am happy to receive feedbacks, good or bad 💪. Thanks again and I’ll see you soon. 👋  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[MacOS Dev Environment Setup]]></title><description><![CDATA[Today, I am going to share with you guys my development environment which has been serving me really well for the past year. By all means…]]></description><link>https://nartc.netlify.com/blogs/macbook-dev-env/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/macbook-dev-env/</guid><pubDate>Thu, 19 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today, I am going to share with you guys my &lt;strong&gt;development environment&lt;/strong&gt; which has been serving me really well for the past year. By all means, mine is not that special or anything but I want to share because there might be people out there who might find this interesting, and for me to have a source that I could come back to every time I install &lt;code class=&quot;language-text&quot;&gt;Parallels&lt;/code&gt; 😂&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Parallels&lt;/code&gt; is a piece of software that lets you run &lt;code class=&quot;language-text&quot;&gt;Windows&lt;/code&gt; on a &lt;code class=&quot;language-text&quot;&gt;Mac&lt;/code&gt;. They’re doing a very good job but I just don’t like installing &lt;code class=&quot;language-text&quot;&gt;VMs&lt;/code&gt; on my machine. We have &lt;code class=&quot;language-text&quot;&gt;Dockers&lt;/code&gt; now you know?! tldr; I’ve had &lt;em&gt;not so good&lt;/em&gt; experiences with &lt;code class=&quot;language-text&quot;&gt;Parallels&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, if you’re a developer, or developer-to-be and wants to setup your &lt;code class=&quot;language-text&quot;&gt;Macbook&lt;/code&gt; for &lt;strong&gt;development&lt;/strong&gt;, I’ll pick you up right here after you’re finishing &lt;code class=&quot;language-text&quot;&gt;Setup your Mac for first use&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I use &lt;a href=&quot;https://sourabhbajaj.com/mac-setup/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;https://sourabhbajaj.com/mac-setup/&lt;/a&gt; as my reference but mine is more concentrated on &lt;code class=&quot;language-text&quot;&gt;JavaScript Dev&lt;/code&gt;. Please check out &lt;a href=&quot;https://sourabhbajaj.com/mac-setup/SystemPreferences/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;this guide&lt;/a&gt; for &lt;strong&gt;System Preferences&lt;/strong&gt; related setup.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;1-install-xcode&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-install-xcode&quot; aria-label=&quot;1 install xcode permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. Install Xcode&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Quick tip: you can start setting up your &lt;strong&gt;System Preferences&lt;/strong&gt; when you’re waiting for &lt;code class=&quot;language-text&quot;&gt;Xcode&lt;/code&gt; to finish installed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Open &lt;code class=&quot;language-text&quot;&gt;AppStore&lt;/code&gt; and install &lt;code class=&quot;language-text&quot;&gt;Xcode&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;After &lt;code class=&quot;language-text&quot;&gt;Xcode&lt;/code&gt; finishes, open your &lt;code class=&quot;language-text&quot;&gt;Terminal&lt;/code&gt; and run the following command which will install &lt;code class=&quot;language-text&quot;&gt;Xcode Command Line Tools&lt;/code&gt; which is required for many other tools, especially &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;72098769367685980000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
xcode-select --install
 `, `72098769367685980000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
xcode-select --install
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;2-homebrew&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-homebrew&quot; aria-label=&quot;2 homebrew permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. Homebrew&lt;/h3&gt;
&lt;p&gt;Next, we’ll install &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt; is like &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt; but for your systems rather than your JS applications. With &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt;, you can install all kind of tools/applications and manages them in one place. Open your &lt;code class=&quot;language-text&quot;&gt;Terminal&lt;/code&gt; and run the following command:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;32722400042443645000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
/usr/bin/ruby -e &amp;quot;\$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)&amp;quot;
 `, `32722400042443645000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
/usr/bin/ruby -e &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After the process is finished, you can run &lt;code class=&quot;language-text&quot;&gt;brew doctor&lt;/code&gt; in the same terminal to check if “your system is ready to brew”. Once you’re “ready”, let’s run:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;57158914977949295000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew tap caskroom/cask
 `, `57158914977949295000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew tap caskroom/cask
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Following are some most used &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt; commands that you’ll probably use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To search for a package (or &lt;strong&gt;Formulae&lt;/strong&gt; or &lt;strong&gt;Cask&lt;/strong&gt; in &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt; vocabulary):&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;60490949242247690000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew search search_phrase
 `, `60490949242247690000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew search search_phrase
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;To install a &lt;strong&gt;formulae&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;30292555856516470000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew install formulae_name
 `, `30292555856516470000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; formulae_name
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;To install a &lt;strong&gt;cask&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;60144037896104480000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew cask install cask_name
 `, `60144037896104480000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; cask_name
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2c621486c2aed06f4fe0ba23aad4a266/caada/brew-search.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 24.375000000000004%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA30lEQVQY04WQzVLDMAyE8z4Ql8b5syzLiXFDaUuhnQ4n3v81FiUBTjAcvlnJ41mtVLwnxnStEfKAnCewCGQYIXHA/vmA08t50elpj5R3SI8ZxAGdI/S/UGxti+xHZI4InsHkwexB5BACQyTAWouyvIcx5b8UZ3/ER7gqN1zoiDd/QFU9qEGJzcYszB+/65nZ/C+KpAnk9IphTBh0FVHmhN7TT8qlJ1Ll5d3Mw8w6aDW60/rL0DuHbUyouh513cAqddOhaQl161a0DzlCdhEuEJx49Ex65wk9id4uwFFc9BMWvaXZAE+YMwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;brew search&quot;
        title=&quot;brew search&quot;
        src=&quot;/static/2c621486c2aed06f4fe0ba23aad4a266/1bed9/brew-search.png&quot;
        srcset=&quot;/static/2c621486c2aed06f4fe0ba23aad4a266/7b64c/brew-search.png 160w,
/static/2c621486c2aed06f4fe0ba23aad4a266/4e610/brew-search.png 320w,
/static/2c621486c2aed06f4fe0ba23aad4a266/1bed9/brew-search.png 640w,
/static/2c621486c2aed06f4fe0ba23aad4a266/7d769/brew-search.png 960w,
/static/2c621486c2aed06f4fe0ba23aad4a266/caada/brew-search.png 1270w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;using Homebrew to search for VS Code&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;the little ✅ next to the &lt;strong&gt;cask&lt;/strong&gt; annotates that this &lt;strong&gt;cask&lt;/strong&gt; is already installed on my machine.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;3-iterm2--alfred&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-iterm2--alfred&quot; aria-label=&quot;3 iterm2  alfred permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. iTerm2 &amp;#x26; Alfred&lt;/h3&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt; installed, you should start installing two things: &lt;code class=&quot;language-text&quot;&gt;iTerm2&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Alfred 4&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;48389155339292820000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew cask install iterm2
brew cask install alfred
 `, `48389155339292820000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; iterm2
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; alfred
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run &lt;code class=&quot;language-text&quot;&gt;iTerm2&lt;/code&gt; and start setting a couple of things up. &lt;strong&gt;The following items are all optional&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to &lt;code class=&quot;language-text&quot;&gt;Preferences -&amp;gt; Profiles -&amp;gt; Keys&lt;/code&gt;, and add new 4 &lt;strong&gt;shortcuts&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;shortcut&lt;/th&gt;
&lt;th&gt;action&lt;/th&gt;
&lt;th&gt;esc+&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;⌘←&lt;/td&gt;
&lt;td&gt;Send Escape Sequence&lt;/td&gt;
&lt;td&gt;OH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⌘→&lt;/td&gt;
&lt;td&gt;Send Escape Sequence&lt;/td&gt;
&lt;td&gt;OF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⌥←&lt;/td&gt;
&lt;td&gt;Send Escape Sequence&lt;/td&gt;
&lt;td&gt;b&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⌥→&lt;/td&gt;
&lt;td&gt;Send Escape Sequence&lt;/td&gt;
&lt;td&gt;f&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;Go to &lt;code class=&quot;language-text&quot;&gt;Preferences -&amp;gt; Profiles -&amp;gt; Session&lt;/code&gt;, and check &lt;code class=&quot;language-text&quot;&gt;Status bar enabled&lt;/code&gt; and configure them how you want. I personally have: &lt;code class=&quot;language-text&quot;&gt;Current Directory&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;CPU Utilization&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Memory Utilization&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8182e546b52d2c409f3703a1059a7680/05775/status-bar-iterm.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 55.625%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAABYlAAAWJQFJUiTwAAAB1klEQVQoz41T23LaQAzdv2gLtrFJCARs1ncb8AVMwBdwgqdTaP//Q061S0iTzmTahzPSSKvV0dEua5oDmqbB8XhEXdfI8xxJkiJNr4jjGGEYIgiCN3tDFEUfcgJsRcU/zhe07QtMi6PrvuNy+QXb8VBVDc7nnyjJ+n6Iw7HFifL7sqa8K/P5ukAQxmifT0RmA5amOZ52e3lZWdYyOOcOxUrMzDnSbI0d+aOHiYyJC13XJzYLVPUBj1NT1jy/dNhud2B+EGK9KTCeTCHYLpYJjOG9ZBUEEWzbpfwWnh8goebxYoX70Vg2jeKlPCt8EZ/NLDDBQnQSBXd3I2yoeEi22D7hdOqIwYw0zaQUHo395WsP2sCAog7Q66uvviZ9EWMpsVpnOVbLJVzPhet78AIf3LYlOzEe5zZJYmE+59Ln/GZtYvfHF3FmmRY8omySFuPpFDx0wSMXD+NHOhzSpTGNOMFANwjDf4LpxhB9RYOi6VAFVF1Sl742eIX+32BCVKHDe4hOwqqa8Wnh3zU3SIZXRlcmfYXE7ilS5M/GvC3lG50TVk5IixGWZVlGmy1QFAVtM0HbVPSYz7TVjh5zQBracBznDTZB/Izdfk8f4CJt27b0yCv5234DpKZYK3iTergAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;status bar iterm&quot;
        title=&quot;status bar iterm&quot;
        src=&quot;/static/8182e546b52d2c409f3703a1059a7680/1bed9/status-bar-iterm.png&quot;
        srcset=&quot;/static/8182e546b52d2c409f3703a1059a7680/7b64c/status-bar-iterm.png 160w,
/static/8182e546b52d2c409f3703a1059a7680/4e610/status-bar-iterm.png 320w,
/static/8182e546b52d2c409f3703a1059a7680/1bed9/status-bar-iterm.png 640w,
/static/8182e546b52d2c409f3703a1059a7680/7d769/status-bar-iterm.png 960w,
/static/8182e546b52d2c409f3703a1059a7680/f3baa/status-bar-iterm.png 1280w,
/static/8182e546b52d2c409f3703a1059a7680/05775/status-bar-iterm.png 1768w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Status Bar Components&lt;/em&gt;  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you want to change your typography, go to &lt;code class=&quot;language-text&quot;&gt;Preferences -&amp;gt; Profiles -&amp;gt; Text&lt;/code&gt;. I use &lt;code class=&quot;language-text&quot;&gt;Menlo 14pt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Finally, browse to &lt;a href=&quot;https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/schemes&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;iTerm2-Color-Schemes&lt;/a&gt; to pick a theme that you like. Then go to &lt;code class=&quot;language-text&quot;&gt;Preferences -&amp;gt; Profiles -&amp;gt; Colors&lt;/code&gt;, import the preset that you picked and select it.  I personally use &lt;code class=&quot;language-text&quot;&gt;Dracula&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next up is &lt;code class=&quot;language-text&quot;&gt;Alfred 4&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;Alfred&lt;/code&gt; is &lt;code class=&quot;language-text&quot;&gt;Spotlight&lt;/code&gt; replacement and if you’re willing to pay (which you should) for the &lt;code class=&quot;language-text&quot;&gt;Power Pack&lt;/code&gt;, you’ll never live your life normally without &lt;code class=&quot;language-text&quot;&gt;Alfred&lt;/code&gt;. First of all, we need to disable &lt;code class=&quot;language-text&quot;&gt;Spotlight&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;Spotlight&lt;/code&gt; and uncheck everything that you don’t want. I uncheck &lt;code class=&quot;language-text&quot;&gt;Fonts&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Images&lt;/code&gt; and such.&lt;/li&gt;
&lt;li&gt;Click on &lt;code class=&quot;language-text&quot;&gt;Keyboard Shortcuts&lt;/code&gt; and uncheck &lt;code class=&quot;language-text&quot;&gt;Show Spotlight Search&lt;/code&gt;. While you’re here, click on &lt;code class=&quot;language-text&quot;&gt;Services&lt;/code&gt;, look for &lt;code class=&quot;language-text&quot;&gt;Search man Page Index in Terminal&lt;/code&gt; and uncheck that as well. I will explain later.&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;Alfred&lt;/code&gt;. Check &lt;code class=&quot;language-text&quot;&gt;Launch Alfred at login&lt;/code&gt; and change your &lt;code class=&quot;language-text&quot;&gt;Alfred Hotkey&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;⌘ Space&lt;/code&gt;. Then you’re all set.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;4-zsh-and-oh-my-zsh&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-zsh-and-oh-my-zsh&quot; aria-label=&quot;4 zsh and oh my zsh permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. zsh and oh-my-zsh&lt;/h3&gt;
&lt;p&gt;One of the reasons why &lt;code class=&quot;language-text&quot;&gt;iTerm2&lt;/code&gt; is so much more powerful than &lt;code class=&quot;language-text&quot;&gt;Terminal&lt;/code&gt; is that you can customize it. There are many different &lt;em&gt;frameworks&lt;/em&gt; that can make your &lt;code class=&quot;language-text&quot;&gt;iTerm2&lt;/code&gt; experience up another level. Personally, I always go with &lt;code class=&quot;language-text&quot;&gt;zsh&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;oh-my-zsh&lt;/code&gt; because of how well-known it is, easy to look for answers you know 😋. To install &lt;code class=&quot;language-text&quot;&gt;zsh&lt;/code&gt;, we’ll use &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt;.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;4233084405710419000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew install zsh
 `, `4233084405710419000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After that’s done, run the following command to install &lt;code class=&quot;language-text&quot;&gt;oh-my-zsh&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;13969508897543715000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
sh -c &amp;quot;\$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&amp;quot;
 `, `13969508897543715000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
&lt;span class=&quot;token function&quot;&gt;sh&lt;/span&gt; -c &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you have the power of &lt;code class=&quot;language-text&quot;&gt;oh-my-zsh&lt;/code&gt; in your &lt;code class=&quot;language-text&quot;&gt;iTerm2&lt;/code&gt;. Your main configuration file will be &lt;code class=&quot;language-text&quot;&gt;~/.zshrc&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;~/.bash_profile&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;~/.bashrc&lt;/code&gt;. We’ll start setting up &lt;code class=&quot;language-text&quot;&gt;oh-my-zsh&lt;/code&gt; with some productivity stuffs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By default, &lt;code class=&quot;language-text&quot;&gt;zsh&lt;/code&gt; provides an &lt;code class=&quot;language-text&quot;&gt;alias&lt;/code&gt; to quickly open &lt;code class=&quot;language-text&quot;&gt;~/.zshrc&lt;/code&gt; from the terminal. However, you might want to install your favorite text editor before doing so. I usually install &lt;code class=&quot;language-text&quot;&gt;nvim&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;vscode&lt;/code&gt; at this point.&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;14676927669414197000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew install nvim
brew cask install visual-studio-code
 `, `14676927669414197000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; nvim
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; visual-studio-code
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;nvim&lt;/code&gt; feels easier to me and &lt;code class=&quot;language-text&quot;&gt;VSCode&lt;/code&gt; has that &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; command that you can open &lt;code class=&quot;language-text&quot;&gt;VSCode&lt;/code&gt; from the terminal. Go ahead and execute:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;72380330676358630000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
nvim ~/.zshrc
 `, `72380330676358630000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
nvim ~/.zshrc
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; if you want to. If &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; is not available, run &lt;code class=&quot;language-text&quot;&gt;Visual Studio Code&lt;/code&gt; -&gt; Open the &lt;code class=&quot;language-text&quot;&gt;Command Palette&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;Shell Command: install &amp;#39;code&amp;#39; command in PATH&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;alias&lt;/code&gt; is your shortcut to any shell/combinations of shell -  &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let’s setup some aliases to make your life easier. The following list is my current aliases which I find super helpful.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;53276050573085000000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
# change to code if you use vscode
alias zshconfig=&amp;quot;nvim ~/.zshrc&amp;quot;
# you need to source zshrc after you make change like adding plugins
alias zshsource=&amp;quot;source ~/.zshrc&amp;quot;
# quickly open oh-my-zsh config
alias ohmyzsh=&amp;quot;code ~/.oh-my-zsh&amp;quot;
# best alias ever
alias c=&amp;quot;clear&amp;quot;

alias rm=&amp;quot;rm -rf&amp;quot;
alias ls=&amp;quot;ls -lah&amp;quot;
alias cd..=&amp;quot;cd ..&amp;quot;

# find node_modules recursively from the current dir
alias findnode=&amp;quot;find . -name &amp;quot;node_modules&amp;quot; -type d -prune -print | xargs du -chs&amp;quot;
# remove those node_modules
alias rmnode=&amp;quot;find . -name &apos;node_modules&apos; -type d -prune -print -exec rm -rf &apos;{}&apos; \;&amp;quot;

# if you develop iOS app, this will list all available simulators
alias listios=&amp;quot;xcrun simctl list devices&amp;quot;

# CLI Alias
alias cra=&amp;quot;create-react-app&amp;quot;
alias crl=&amp;quot;create-react-library&amp;quot;
alias rn=&amp;quot;react-native&amp;quot;
 `, `53276050573085000000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt; 
&lt;span class=&quot;token comment&quot;&gt;# change to code if you use vscode&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;zshconfig&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;nvim ~/.zshrc&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# you need to source zshrc after you make change like adding plugins&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;zshsource&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;source ~/.zshrc&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# quickly open oh-my-zsh config&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ohmyzsh&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;code ~/.oh-my-zsh&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# best alias ever&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;clear&quot;&lt;/span&gt;

&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;rm&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;rm -rf&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;ls&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ls -lah&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; cd&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cd ..&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# find node_modules recursively from the current dir&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;findnode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find . -name &quot;&lt;/span&gt;node_modules&lt;span class=&quot;token string&quot;&gt;&quot; -type d -prune -print | xargs du -chs&quot;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# remove those node_modules&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;rmnode&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find . -name &apos;node_modules&apos; -type d -prune -print -exec rm -rf &apos;{}&apos; \;&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# if you develop iOS app, this will list all available simulators&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;listios&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;xcrun simctl list devices&quot;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# CLI Alias&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;cra&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;create-react-app&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;crl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;create-react-library&quot;&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;rn&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;react-native&quot;&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you’re from &lt;code class=&quot;language-text&quot;&gt;~/.bash_profile&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;~/.bashrc&lt;/code&gt;, you’ll need to add the next line to your &lt;code class=&quot;language-text&quot;&gt;~/.zshrc&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;32602054035353346000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
# If you come from bash you might have to change your \$PATH.
export PATH=\$HOME/bin:/usr/local/bin:\$PATH
 `, `32602054035353346000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt; 
&lt;span class=&quot;token comment&quot;&gt;# If you come from bash you might have to change your $PATH.&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PATH&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/bin:/usr/local/bin:&lt;span class=&quot;token environment constant&quot;&gt;$PATH&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;68952035293946580000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
# extraneous stuffs
export CLICOLOR=1
export LC_ALL=en_US.UTF-8
 `, `68952035293946580000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt; 
&lt;span class=&quot;token comment&quot;&gt;# extraneous stuffs&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;CLICOLOR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;LC_ALL&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;en_US.UTF-8
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Theming: You can go to &lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh/wiki/Themes&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Themes&lt;/a&gt; and pick a theme you like. Then edit the following line&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;58458987092472906000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
ZSH_THEME=&amp;quot;theme_name&amp;quot;
 `, `58458987092472906000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt; 
&lt;span class=&quot;token assign-left variable&quot;&gt;ZSH_THEME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;theme_name&quot;&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Plugins. By default, &lt;code class=&quot;language-text&quot;&gt;zsh&lt;/code&gt; comes with various plugins and will enable &lt;code class=&quot;language-text&quot;&gt;git&lt;/code&gt; plugin by default. &lt;code class=&quot;language-text&quot;&gt;git&lt;/code&gt; plugin provides you with all kinds of &lt;code class=&quot;language-text&quot;&gt;git&lt;/code&gt; shortcuts. Check this &lt;a href=&quot;https://kapeli.com/cheat_sheets/Oh-My-Zsh_Git.docset/Contents/Resources/Documents/index&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;link&lt;/a&gt; out. I have the following plugins enabled.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;colored-man-pages&lt;/code&gt;: comes with &lt;code class=&quot;language-text&quot;&gt;zsh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;colorize&lt;/code&gt;: comes with &lt;code class=&quot;language-text&quot;&gt;zsh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;zsh-syntax-highlighting&lt;/code&gt;: &lt;a href=&quot;https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/INSTALL.md#oh-my-zsh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;INSTALL.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;zsh-autosuggestions&lt;/code&gt;: &lt;a href=&quot;https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md#oh-my-zsh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;INSTALL.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;zsh-completions&lt;/code&gt;:  &lt;a href=&quot;https://github.com/zsh-users/zsh-completions#oh-my-zsh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;INSTALL.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that we have setup our terminal, it’s time to start installing some applications. Use &lt;code class=&quot;language-text&quot;&gt;brew search&lt;/code&gt; to search for an app that you want.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;71699916622660240000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew cask install google-chrome
brew cask install appcleaner
brew cask install postman
 `, `71699916622660240000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; google-chrome
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; appcleaner
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; postman
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;5-nodejs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-nodejs&quot; aria-label=&quot;5 nodejs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. NodeJS&lt;/h3&gt;
&lt;p&gt;There are many ways to install &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; but I’d recommend using &lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt; to manage &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; on your machine. &lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt; stands for &lt;code class=&quot;language-text&quot;&gt;Node Version Manager&lt;/code&gt; and it allows you to install and switch between versions very easily.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;26146827644381300000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash
 `, `26146827644381300000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
&lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;zshsource&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;command -v nvm&lt;/code&gt; to check if &lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt; is available. If you have issue, it’s most likely that &lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt; is missing in your &lt;code class=&quot;language-text&quot;&gt;PATH&lt;/code&gt;. Fix by adding the following block to your &lt;code class=&quot;language-text&quot;&gt;~/.zshrc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;38801498941247185000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
export NVM_DIR=&amp;quot;\$HOME/.nvm&amp;quot;
[ -s &amp;quot;\$NVM_DIR/nvm.sh&amp;quot; ] &amp;&amp; \. &amp;quot;\$NVM_DIR/nvm.sh&amp;quot;  # This loads nvm
[ -s &amp;quot;\$NVM_DIR/bash_completion&amp;quot; ] &amp;&amp; \. &amp;quot;\$NVM_DIR/bash_completion&amp;quot;  # This loads nvm bash_completion
 `, `38801498941247185000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-shell line-numbers&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt; 
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;NVM_DIR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.nvm&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; -s &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$NVM_DIR&lt;/span&gt;/nvm.sh&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;. &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$NVM_DIR&lt;/span&gt;/nvm.sh&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# This loads nvm&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; -s &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$NVM_DIR&lt;/span&gt;/bash_completion&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;. &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$NVM_DIR&lt;/span&gt;/bash_completion&quot;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;# This loads nvm bash_completion&lt;/span&gt;
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;nvm install node&lt;/code&gt;. This will install the latest version of &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt; on your machine.&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;nvm ls&lt;/code&gt; to list installed &lt;code class=&quot;language-text&quot;&gt;Node&lt;/code&gt; versions.&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;nvm ls-remote&lt;/code&gt; to list &lt;code class=&quot;language-text&quot;&gt;Node&lt;/code&gt; versions that you can install&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;6-python&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-python&quot; aria-label=&quot;6 python permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Python&lt;/h3&gt;
&lt;p&gt;Even though I don’t use &lt;code class=&quot;language-text&quot;&gt;Python&lt;/code&gt; as a programming language, but some tools are built with &lt;code class=&quot;language-text&quot;&gt;Python&lt;/code&gt;. So I’d also recommend installing &lt;code class=&quot;language-text&quot;&gt;Python&lt;/code&gt; using &lt;code class=&quot;language-text&quot;&gt;pyenv&lt;/code&gt; (just like &lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt; for &lt;code class=&quot;language-text&quot;&gt;NodeJS&lt;/code&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Install &lt;code class=&quot;language-text&quot;&gt;pyenv&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;97273849162457150000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew install pyenv
 `, `97273849162457150000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; pyenv
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Update &lt;code class=&quot;language-text&quot;&gt;PATH&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;88769849301516570000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
echo &apos;eval &amp;quot;\$(pyenv init -)&amp;quot;&apos; &gt;&gt; ~/.zshrc
 `, `88769849301516570000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;eval &quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;pyenv init -&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; ~/.zshrc
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;pyenv install --list&lt;/code&gt;. If you have issue here, restart your terminal.&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;pyenv install version_here&lt;/code&gt; to install &lt;code class=&quot;language-text&quot;&gt;Python&lt;/code&gt;. I usually install latest 2.x and latest 3.x&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;7-database&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-database&quot; aria-label=&quot;7 database permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7, Database&lt;/h3&gt;
&lt;p&gt;Again, consult &lt;a href=&quot;https://sourabhbajaj.com/mac-setup/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;https://sourabhbajaj.com/mac-setup/&lt;/a&gt; and pick the ones that are relevant to you.&lt;/p&gt;
&lt;h3 id=&quot;8-docker&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-docker&quot; aria-label=&quot;8 docker permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. Docker&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;Docker&lt;/code&gt; can be installed by visiting this &lt;a href=&quot;https://docs.docker.com/docker-for-mac/install/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;link&lt;/a&gt;. If you like GUI, I’d recommend &lt;code class=&quot;language-text&quot;&gt;Kitematic&lt;/code&gt; which is awesome.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;25131020733418795000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew cask install kitematic
 `, `25131020733418795000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; kitematic
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/07af15531d17df173d55323e87b7da8a/b4f91/kitematic.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 63.125%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAABYlAAAWJQFJUiTwAAACZ0lEQVQ4y3VTPWtUQRTd/6B/QkvFQrDRyk4UCxECEixECwWxETSCsghaKAha+UGKRFCLkPiFkRh2CVGySEBsLMzGYHazu++9eTNvvt/xzuQlRo0Dl7szc+e8c+49W1PZKrjLgRLgUkE5DwfA+BKGfsdchd3IZYmSwnv/O6p9jQmFLOMIiJpAM2mwlvKYufFg0oIpi4K+oijCGdcOhTJI6W0hNURRZYqa0gpcCHgggr7rSIx8SfCj00OSssgyFxLXrtfR+NSCDeyNhbZ0rgKw/SNqUil0e31kooiQd74r7GoyJElKzBm0IaZcYO/+A3gxMQlHkiMB7+jOESsT2YYcIgKudteQ0aOwHrcLHP6YUrGFpZBEfSkrMHRyCM3mXKxR2qCrPRJqh4xgWxgqrSPDJM1i8fT8Z9QfjKLDBJy1UaJgHEuHDuLn1CtI2lt6o6wDDyCB2VbJhiSlJC18NaxnHxZw+tYjKGKulaZB0WRzDrZjJ7KxcSQ0OEF7SezVpuQtgKiW8+tjmZxfxPn7T2NxkFwQwEoq8PX4UfRmZ6FDrXP/l1xWngpFYY2/nsapK3Usd3tkBwlrgyyFS1fPYKYxQwNRce/pXG/HcAPQVoD3nk9hz/CFONmM5Ui5RD8vcHZ4GHONJkywC90xbSGCH//u4QagrwAXpt/i4Y0R8pgha1D/SPIyAd4eu4zWtxb5b709fboYbCcZm020MfmJJ3AXj2FAg4p/xYImanLcXDyBZvsNBj1ix3M4o7eXnNsSCYUhK4Q5Z6N30T2ym3xZgNE0M6GxIjjOvd+HufZLKLJryhg6dM7Uv5J/AQjZy2Oum/iyAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;kitematic&quot;
        title=&quot;kitematic&quot;
        src=&quot;/static/07af15531d17df173d55323e87b7da8a/1bed9/kitematic.png&quot;
        srcset=&quot;/static/07af15531d17df173d55323e87b7da8a/7b64c/kitematic.png 160w,
/static/07af15531d17df173d55323e87b7da8a/4e610/kitematic.png 320w,
/static/07af15531d17df173d55323e87b7da8a/1bed9/kitematic.png 640w,
/static/07af15531d17df173d55323e87b7da8a/7d769/kitematic.png 960w,
/static/07af15531d17df173d55323e87b7da8a/f3baa/kitematic.png 1280w,
/static/07af15531d17df173d55323e87b7da8a/b4f91/kitematic.png 2152w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Kitematic&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;9-mongodb&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#9-mongodb&quot; aria-label=&quot;9 mongodb permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;9. MongoDB&lt;/h3&gt;
&lt;p&gt;I use &lt;code class=&quot;language-text&quot;&gt;Docker&lt;/code&gt; for my local &lt;code class=&quot;language-text&quot;&gt;MongoDB&lt;/code&gt; instance. However, I recently had to install &lt;code class=&quot;language-text&quot;&gt;Mongo&lt;/code&gt; client on my machine due to some work that requires some CLIs from &lt;code class=&quot;language-text&quot;&gt;Mongo&lt;/code&gt;. Visit this &lt;a href=&quot;https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;link&lt;/a&gt; and follow the manual to install &lt;code class=&quot;language-text&quot;&gt;Mongo&lt;/code&gt; locally.&lt;/p&gt;
&lt;p&gt;Again, I like GUI because it saves a lot of times and there are many &lt;code class=&quot;language-text&quot;&gt;Mongo GUI Client&lt;/code&gt; out there for you to choose: &lt;strong&gt;Studio 3T&lt;/strong&gt; 💰, &lt;strong&gt;NoSQL Booster&lt;/strong&gt; 💰 or &lt;strong&gt;Mongo Compass&lt;/strong&gt; 🆓 and &lt;strong&gt;Robo 3T&lt;/strong&gt; 🆓. I personally like &lt;code class=&quot;language-text&quot;&gt;NoSQL Booster&lt;/code&gt; (they also have free version) because of their focus on &lt;code class=&quot;language-text&quot;&gt;Shell&lt;/code&gt; commands and provides extremely good intellisense.&lt;/p&gt;
&lt;h3 id=&quot;10-jetbrains&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#10-jetbrains&quot; aria-label=&quot;10 jetbrains permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;10. Jetbrains&lt;/h3&gt;
&lt;p&gt;I am a &lt;strong&gt;Jetbrains&lt;/strong&gt; fan. &lt;strong&gt;Jetbrains&lt;/strong&gt; is a suite of well-known IDEs like &lt;strong&gt;IntelliJ&lt;/strong&gt;, &lt;strong&gt;Webstorm&lt;/strong&gt;, &lt;strong&gt;PyCharm&lt;/strong&gt;, &lt;strong&gt;PHPStorm&lt;/strong&gt;, &lt;strong&gt;Android Studio&lt;/strong&gt; ..etc… Only thing to note here is if you use &lt;strong&gt;Jetbrains&lt;/strong&gt;, consider installing their toolbox &lt;strong&gt;Jetbrains Toolbox&lt;/strong&gt; and it’s available via &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;48658411421854830000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(` 
brew cask install jetbrains-toolbox
 `, `48658411421854830000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-bash line-numbers&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt; 
brew cask &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; jetbrains-toolbox
 &lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Jetbrains Toolbox&lt;/strong&gt; allows you to manage your IDEs installation and versions. It also allows you to install certain &lt;code class=&quot;language-text&quot;&gt;shell&lt;/code&gt; commands so you can open your IDEs from the terminal.&lt;/p&gt;
&lt;p&gt;That is all I have to share for &lt;strong&gt;Development Environment Setup&lt;/strong&gt;. I hope you find the information helpful. My next blob will probably be on &lt;strong&gt;Jetbrains&lt;/strong&gt; specific so I can share my productivity tips with you through the tools that we use everyday. Go and be productive, and make sure to always install things with &lt;code class=&quot;language-text&quot;&gt;Homebrew&lt;/code&gt; whenever possible. Thanks for reading 😀.  &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Slalom Health Equity Hackathon - Part 2]]></title><description><![CDATA[Welcome back to part 2 (and probably final part) of my journey through Slalom Health Equity Hackathon. As mentioned towards the end of Part…]]></description><link>https://nartc.netlify.com/blogs/slalom-health-equity-hackathon-2/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/slalom-health-equity-hackathon-2/</guid><pubDate>Thu, 12 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Welcome back to part 2 (and probably final part) of my journey through &lt;strong&gt;Slalom Health Equity Hackathon&lt;/strong&gt;. As mentioned towards the end of &lt;a href=&quot;/blogs/slalom-health-equity-hackathon-1&quot;&gt;Part 1&lt;/a&gt;, this part will start getting into the weed of fine-tuning the data after we have tried fetching and consolidating everything we’re provided by the organizers.&lt;/p&gt;
&lt;p&gt;The agenda for this part will be as follow:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Web Scraping&lt;/li&gt;
&lt;li&gt;AWS Comprehend&lt;/li&gt;
&lt;li&gt;Presentation&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;It’s worth noting that the organizers did provide an &lt;strong&gt;API Endpoint&lt;/strong&gt; for participants to make a request by sending their data and the &lt;strong&gt;endpoint&lt;/strong&gt; will return a set of scores so participants could see how they’re doing and what they should be improving on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;web-scraping&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#web-scraping&quot; aria-label=&quot;web scraping permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Web Scraping&lt;/h3&gt;
&lt;p&gt;Before our team resorted to &lt;strong&gt;Web Scraping&lt;/strong&gt;, we were actually thinking about two different APIs:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.google.com/maps-platform/places/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Google Places API&lt;/a&gt;: This is a Google’s service that provides information about businesses.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://azure.microsoft.com/en-us/services/cognitive-services/bing-entity-search-api/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Bing Entity Search API&lt;/a&gt;: This is pretty much the same service as above but provided by Bing.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.google.com/custom-search/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Google Custom Search API&lt;/a&gt;: This API will allow you to build your custom search.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With the amount of data we had, there’s no way to utilize these two APIs without paying or taking turns creating multiple free accounts (which was totally valid) but I’d rather do something simple, quick, and less bothering, especially to my teammates.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;My teammates was working with &lt;strong&gt;Python&lt;/strong&gt;, namely &lt;strong&gt;jupyter&lt;/strong&gt; and &lt;strong&gt;boto3&lt;/strong&gt; to get familiar and adapt to &lt;strong&gt;AWS Comprehend&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For projects that are not in Hackathon format, I would totally suggest going for a well-known and fully supported API like &lt;strong&gt;Google Places&lt;/strong&gt;. What I am about to do is fun, somewhat effective, and pretty inaccurate 😅&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;After every consideration for not wanting to pay 3rd-party services, we decided to go with &lt;a href=&quot;https://developers.google.com/custom-search/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Puppeteer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/91f668eb062309c46a488850791dc223/0d4f8/puppeteer.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 38.125%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsSAAALEgHS3X78AAABeklEQVQY01WQzUoCURiGv3OO4doIvIKuo7atJUpwEVRX0RW0Lmgnofk31jiajjLqOH86jqkz/iQlEgS1KSqSdhnTcRwXXsDzPg8veEZRz32MDBNkkCL9NOldE5PFXQ7aHOnkkXELBo+NEm4KSK+gehVpNaTKSFGRrIFndEWGcTJIkD5Demli3eAu6zVzG/0SNDN+q+zrVEAvYb2MGhQWkSohRUayClIdHG3c0TJzrcUSM0NamYPJ3cn7w/FTd12nK4IDL7QUVuZaqQFucz+10M6bezm/Wdx/NALjVmjc9qkFT6vqaimsOM2SBjUdVpupmcNqAhfCmI9AMYr4GGIjUMk5Wgq7zYg2L2G3ec1kweJ2yunDQiogCnsCvyuVg/nMNp8FXVxprtVBbFI46TQztNlrcdBi2M9X27Z/OdY+Cs7OL+yZLU2/QKvgxc+y83OtAaIBZJBcXuXABpOdfrx9T+TQlnZ6+RzetF/OxJ8/UAWsyVhV3J9ps2j8AzCWATB2uv3GAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;puppeteer&quot;
        title=&quot;puppeteer&quot;
        src=&quot;/static/91f668eb062309c46a488850791dc223/1bed9/puppeteer.png&quot;
        srcset=&quot;/static/91f668eb062309c46a488850791dc223/7b64c/puppeteer.png 160w,
/static/91f668eb062309c46a488850791dc223/4e610/puppeteer.png 320w,
/static/91f668eb062309c46a488850791dc223/1bed9/puppeteer.png 640w,
/static/91f668eb062309c46a488850791dc223/7d769/puppeteer.png 960w,
/static/91f668eb062309c46a488850791dc223/f3baa/puppeteer.png 1280w,
/static/91f668eb062309c46a488850791dc223/0d4f8/puppeteer.png 1600w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Google Chrome Puppeteer&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Puppeteer&lt;/strong&gt; is a Google Chrome Headless API that allows you to basically use Chrome programmatically and automatically. For what &lt;strong&gt;Puppeteer&lt;/strong&gt; has to offer, I’d refer you to &lt;strong&gt;Puppeteer README&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9ca7cbb626eaeb3770f0c8eae490cebd/5bfb8/puppeteer_read_me.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 61.24999999999999%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAYAAABiDJ37AAAACXBIWXMAABYlAAAWJQFJUiTwAAACFElEQVQoz41SyY7TQBD1d/E9SHwIR04ckBCCI0duSPwAiwRIM8wk4y1O4i1tO3Z7a8eO4+RR1clIkZCAkp6qu1VV73VVGcvVGjPLgWlaqGWLf9npdCI8+jOOpyOB/PEIY/7rFqvvX/Dtx0/cRF9hxvcozDlC28RnN8WdG2A+m2Fh3mKvCl2UE68LXpvheWvIpQfL8/GwnWEWWhCWi3jl4SYo4AQC3mKBYGliGuo/FVNxP08he4WFiGCU3QGR7CHKEUk+QuQDAjmg6kaM+z2GgbAfMYwT2q5H2yq0qkPTttpjOuLZ+1d48vY5nr5+AUMphTApEaQ1wqxCus2RpQnyokSY99iWLcqyQlnVqJsGVd3oM/uBCKuqwodPH3Hv2nj57g2Mfhigup1Wwr2ZiHE8HIj4iP+xhkjmd/fwabiRH8CI4hhBGCHLttjmOYpCalYOlGVJ6krtpZQoCBwj5fnOMfxDx3Fg2zZiqmUURQEhEqRZBpEkOqHve+x2O7D602UdHjFNk8b1pDme0VJfjYGSoihGFG/gBwFCOvskfU1ggop7V59REXgYHZFdvzF4WHptuDInZqQwJS+E0Go35PmdyfjMyTuK5S+qrqMJK61IXTx/f09DMjoaiGXZcLwVTNcn7+v7g2nCpf1jIkZOreB2cK91gUsRLtxc7h0RGcy62WwgMqlXJymay44pncCrcq2Ee/s3+w0LQovk0B63YwAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;puppeteer_read_me&quot;
        title=&quot;puppeteer_read_me&quot;
        src=&quot;/static/9ca7cbb626eaeb3770f0c8eae490cebd/1bed9/puppeteer_read_me.png&quot;
        srcset=&quot;/static/9ca7cbb626eaeb3770f0c8eae490cebd/7b64c/puppeteer_read_me.png 160w,
/static/9ca7cbb626eaeb3770f0c8eae490cebd/4e610/puppeteer_read_me.png 320w,
/static/9ca7cbb626eaeb3770f0c8eae490cebd/1bed9/puppeteer_read_me.png 640w,
/static/9ca7cbb626eaeb3770f0c8eae490cebd/7d769/puppeteer_read_me.png 960w,
/static/9ca7cbb626eaeb3770f0c8eae490cebd/f3baa/puppeteer_read_me.png 1280w,
/static/9ca7cbb626eaeb3770f0c8eae490cebd/5bfb8/puppeteer_read_me.png 1780w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;Google Chrome Puppeteer README&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The plan was to have Puppeteer running on the dataset, perform a Google Search with the organization name, and fetch the first URL that Google Search returns. This approach is easy and quick but facing these issues: &lt;strong&gt;inaccurate data&lt;/strong&gt; and &lt;strong&gt;advertisement&lt;/strong&gt;. Given our time constraint and hackathon format, we decided to go with it anyway. First, I needed to run a query to query for all the Organizations that &lt;em&gt;DO NOT HAVE&lt;/em&gt; a &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt; yet.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Same ol’ setup to start working &lt;code class=&quot;language-text&quot;&gt;MongoDB&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;JavaScript&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;76193013124392350000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const mongo = require(&apos;mongodb&apos;);

let result = 0;

const client = new mongo.MongoClient(&apos;mongodb://localhost:27017&apos;, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

client.connect((err) =&gt; {
    if (err) {
        console.log(err);
        return;
    }

    const db = client.db(&apos;stl-health-hack&apos;);
    const col = db.collection(&apos;queriedbmfs&apos;);
})`, `76193013124392350000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; col &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;npm install puppeteer&lt;/code&gt; and start with importing &lt;code class=&quot;language-text&quot;&gt;puppeteer&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;6706755351015103000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const puppeteer = require(&apos;puppeteer&apos;);
const mongo = require(&apos;mongodb&apos;);

let result = 0;`, `6706755351015103000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; puppeteer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;puppeteer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Add a query to find all Organizations that do not have &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt; or have invalid &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;52402111255798590000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const puppeteer = require(&apos;puppeteer&apos;);
const mongo = require(&apos;mongodb&apos;);

let result = 0;

const client = new mongo.MongoClient(&apos;mongodb://localhost:27017&apos;, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

client.connect((err) =&gt; {
    if (err) {
        console.log(err);
        return;
    }

    const db = client.db(&apos;stl-health-hack&apos;);
    const col = db.collection(&apos;queriedbmfs&apos;);

    col.find({\$or: [
        {WEBSITE: {\$exists: false}},
        {WEBSITE: {\$eq: &amp;quot;N/A&amp;quot;}},
        {WEBSITE: {\$eq: &amp;quot;NONE&amp;quot;}},
        {WEBSITE:  {\$eq: &amp;quot;None&amp;quot;}}
    ]}).toArray(async (err, bmfs) =&gt; {
        
    });
})`, `52402111255798590000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; puppeteer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;puppeteer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; col &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$or&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$exists&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;N/A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NONE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;None&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bmfs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Loop through the result and call &lt;code class=&quot;language-text&quot;&gt;getFirstUrl()&lt;/code&gt; and pass in the organization name&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;97109752997073470000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const puppeteer = require(&apos;puppeteer&apos;);
const mongo = require(&apos;mongodb&apos;);

let result = 0;

const client = new mongo.MongoClient(&apos;mongodb://localhost:27017&apos;, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

client.connect((err) =&gt; {
    if (err) {
        console.log(err);
        return;
    }

    const db = client.db(&apos;stl-health-hack&apos;);
    const col = db.collection(&apos;queriedbmfs&apos;);

    col.find({\$or: [
        {WEBSITE: {\$exists: false}},
        {WEBSITE: {\$eq: &amp;quot;N/A&amp;quot;}},
        {WEBSITE: {\$eq: &amp;quot;NONE&amp;quot;}},
        {WEBSITE:  {\$eq: &amp;quot;None&amp;quot;}}
    ]}).toArray(async (err, bmfs) =&gt; {
        for (let i = 0; i &lt; bmfs.length; i++) {
            const bmf = bmfs[i];
            const href = await getFirstUrl(bmf.NAME);
        }
    });
})`, `97109752997073470000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; puppeteer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;puppeteer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; col &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$or&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$exists&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;N/A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NONE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;None&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bmfs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; bmf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getFirstUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;I’ll get to &lt;code class=&quot;language-text&quot;&gt;getFirstUrl()&lt;/code&gt; in a bit&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;If &lt;code class=&quot;language-text&quot;&gt;href&lt;/code&gt; (the URL we want) is found, then I want to update the same organization with the newly found URL&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;73175332467353770000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const puppeteer = require(&apos;puppeteer&apos;);
const mongo = require(&apos;mongodb&apos;);

let result = 0;

const client = new mongo.MongoClient(&apos;mongodb://localhost:27017&apos;, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

client.connect((err) =&gt; {
    if (err) {
        console.log(err);
        return;
    }

    const db = client.db(&apos;stl-health-hack&apos;);
    const col = db.collection(&apos;queriedbmfs&apos;);

    col.find({\$or: [
        {WEBSITE: {\$exists: false}},
        {WEBSITE: {\$eq: &amp;quot;N/A&amp;quot;}},
        {WEBSITE: {\$eq: &amp;quot;NONE&amp;quot;}},
        {WEBSITE:  {\$eq: &amp;quot;None&amp;quot;}}
    ]}).toArray(async (err, bmfs) =&gt; {
        for (let i = 0; i &lt; bmfs.length; i++) {
            const bmf = bmfs[i];
            const href = await getFirstUrl(bmf.NAME);
            if (href) {
                await col.updateOne({_id: bmf._id}, {\$set: {WEBSITE: href}});
            }
        }
    });
})`, `73175332467353770000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; puppeteer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;puppeteer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; col &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$or&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$exists&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;N/A&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NONE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;None&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bmfs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; bmf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getFirstUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;                &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; href&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;6&quot;&gt;
&lt;li&gt;Implement &lt;code class=&quot;language-text&quot;&gt;getFirstUrl()&lt;/code&gt;. Everything that happens with &lt;code class=&quot;language-text&quot;&gt;puppeteer&lt;/code&gt; is &lt;strong&gt;asynchronous&lt;/strong&gt; operations so I utilize &lt;code class=&quot;language-text&quot;&gt;async/await&lt;/code&gt; here.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;78936600137580950000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const getFirstUrl = async (query) =&gt; {
    // Just a log for knowing which organization puppeteer is trying to fetch
    console.log(\`Getting URL for \${query}\`);
    
    // Initialize a browser instance. Default value for &amp;quot;headless&amp;quot; is true which means
    // puppeteer will open up a Chrome/Chromium window
    // I set it to &amp;quot;true&amp;quot; explicitly so you can see there&apos;s an option.
    const browser = await puppeteer.launch({headless: true});
    
    // Initialize a new page
    const page = await browser.newPage();
    
    // Go to this URL
    await page.goto(&apos;https://google.com&apos;);

    // Type in the search box the Organization name. 
    // What you pass in .type() is the input selector. 
    // You can find out about the selectors for all elements in the webpage by using Chrome Dev Tools.
    await page.type(&amp;quot;input.gLFyf&amp;quot;, query);
    
    // Hit Enter
    await page.keyboard.press(String.fromCharCode(13))
    
    // Wait for the next page&apos;s done loading
    await page.waitForNavigation();
    
    // Wait additional 2 seconds for no reason at all
    await page.waitFor(2000);
    
    // Try to get the first URL
    let href = await page.\$eval(&amp;quot;div.g&amp;quot;, el =&gt; el.firstElementChild.href);
    if (!href) {
        href = await page.\$eval(&amp;quot;div.r&amp;quot;, el =&gt; el.firstElementChild.href);
    }

    // the next two lines are for &amp;quot;reporting&amp;quot; purposes
    result++;
    console.log(\`Found URL: \${href}. Already ran \${result}\`);
    
    // Close the page
    await page.close();
    
    // Close the browser
    await browser.close();
    
    // return the URL if found, return null if not found
    return href;
}`, `78936600137580950000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;getFirstUrl&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Just a log for knowing which organization puppeteer is trying to fetch&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Getting URL for &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;query&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Initialize a browser instance. Default value for &quot;headless&quot; is true which means&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// puppeteer will open up a Chrome/Chromium window&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// I set it to &quot;true&quot; explicitly so you can see there&apos;s an option.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;headless&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Initialize a new page&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Go to this URL&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://google.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Type in the search box the Organization name. &lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// What you pass in .type() is the input selector. &lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// You can find out about the selectors for all elements in the webpage by using Chrome Dev Tools.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;input.gLFyf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Hit Enter&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keyboard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;press&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fromCharCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Wait for the next page&apos;s done loading&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitForNavigation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Wait additional 2 seconds for no reason at all&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Try to get the first URL&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;div.g&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstElementChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        href &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;div.r&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstElementChild&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// the next two lines are for &quot;reporting&quot; purposes&lt;/span&gt;
    result&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Found URL: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;href&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;. Already ran &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;result&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Close the page&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Close the browser&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// return the URL if found, return null if not found&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; href&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next thing to do is to run the script with &lt;strong&gt;Node&lt;/strong&gt; and watch &lt;strong&gt;Puppeteer&lt;/strong&gt; does its thing. With this approach, our team was able to come down to only 5 organizations that &lt;em&gt;DO NOT&lt;/em&gt; have a &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt;. Well, the websites weren’t really accurate because we didn’t take “Ads” into account when we did “first URL”. At this point, we were also ready to start getting into &lt;strong&gt;AWS Comprehend&lt;/strong&gt;. Our plan was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Train &lt;strong&gt;AWS Comprehend&lt;/strong&gt; to recognize Service Codes by Descriptions: &lt;code class=&quot;language-text&quot;&gt;MISSION_DESC&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;ORG_DESC&lt;/code&gt; and the actual &lt;code class=&quot;language-text&quot;&gt;CODE_DESC&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;fuzzywuzzy string matching&lt;/code&gt; to compare the trained descriptions with the organization’s description.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The goal is to find out which services an organization might provide. And we did just that. With all the information we’ve gotten so far, I was able to whip up quickly an input file in format of a &lt;code class=&quot;language-text&quot;&gt;CSV&lt;/code&gt; so we could feed that into &lt;strong&gt;AWS Comprehend&lt;/strong&gt; via &lt;strong&gt;AWS S3&lt;/strong&gt;&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;72449086043400040000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`db.categories.find({}).forEach((it)=&gt; { 
    let concatDesc = &amp;quot;&amp;quot;;
    if (it.keywords &amp;&amp; it.keywords.length) {
        concatDesc = concatDesc.concat(it.keywords.join(&amp;quot; &amp;quot;));
    }
    
    if (it.description) {
        concatDesc = concatDesc.concat(&amp;quot; &amp;quot;, it.description);
    }
    
    if (concatDesc) {
        db.codedescs.insertOne({code: it.code, description: concatDesc})
    }
});`, `72449086043400040000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;categories&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; concatDesc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keywords &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keywords&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        concatDesc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; concatDesc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keywords&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        concatDesc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; concatDesc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;concatDesc&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;codedescs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insertOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; description&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; concatDesc&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basic query, ain’t it? I concat all the &lt;code class=&quot;language-text&quot;&gt;keywords&lt;/code&gt; associated with a &lt;code class=&quot;language-text&quot;&gt;category&lt;/code&gt; and the &lt;code class=&quot;language-text&quot;&gt;description&lt;/code&gt; of the category, then insert each one in a &lt;code class=&quot;language-text&quot;&gt;codedescs&lt;/code&gt; collection which later allows me to export that collection to &lt;code class=&quot;language-text&quot;&gt;CSV&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;About &lt;strong&gt;AWS Comprehend&lt;/strong&gt;, you’d have to utilize many different components of the &lt;strong&gt;AWS Suite&lt;/strong&gt; like &lt;strong&gt;S3&lt;/strong&gt;, &lt;strong&gt;Permissions Management&lt;/strong&gt;, and couple more that I don’t really recall. Basically, you need to setup in a way that &lt;strong&gt;AWS Comprehend&lt;/strong&gt; can read and write from/to your &lt;strong&gt;S3&lt;/strong&gt; bucket on the same account and region because &lt;strong&gt;Comprehend&lt;/strong&gt; will read the input from &lt;strong&gt;S3&lt;/strong&gt; as well as writing the resutlt to &lt;strong&gt;S3&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once our model has been trained, the comparison starts. We utilized an NPM package called: &lt;code class=&quot;language-text&quot;&gt;fuzzball&lt;/code&gt; &lt;a href=&quot;https://www.npmjs.com/package/fuzzball&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;&lt;/a&gt;. This package is the &lt;code class=&quot;language-text&quot;&gt;JavaScript&lt;/code&gt; implementation of &lt;code class=&quot;language-text&quot;&gt;fuzzywuzzy&lt;/code&gt; methods from &lt;code class=&quot;language-text&quot;&gt;Python&lt;/code&gt;. At a high level, this library contains a set of methods to compare two &lt;code class=&quot;language-text&quot;&gt;strings&lt;/code&gt; and return a ratio of how close the two &lt;code class=&quot;language-text&quot;&gt;strings&lt;/code&gt; match.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, as usual, bring in your libraries. I’ll skip &lt;code class=&quot;language-text&quot;&gt;Mongo&lt;/code&gt; initialization part because it’s identical to previous snippet.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;80964814101646000000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const fuzz = require(&apos;fuzzball&apos;);
const mongo = require(&apos;mongodb&apos;);`, `80964814101646000000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzz &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fuzzball&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Setup our team’s thresholds. These thresholds determine the results. As mentioned above, &lt;code class=&quot;language-text&quot;&gt;fuzzball&lt;/code&gt; returns a ratio and if the ratio is greater than or equal to both thresholds, we accept the result. However, the data was so bad that for a high threshold, we didn’t get anything back. That’s why we iterated through couple of different thresholds to find that “sweet spot”.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;83309182418161630000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const fuzz = require(&apos;fuzzball&apos;);
const mongo = require(&apos;mongodb&apos;);

// ...

/*
 * First set of threshold: 55 - 70
 * Second set of threshold: 30 - 40
 * Third set of threshold: 40 - 55
 * Fourth set of threshold: 35 - 50
 * Fifth set of threshold: 37.5 - 52.5
 */
const fuzzRatio = 37.5;
const fuzzPartialRatio = 52.5;`, `83309182418161630000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzz &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fuzzball&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/*&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt; * First set of threshold: 55 - 70&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt; * Second set of threshold: 30 - 40&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt; * Third set of threshold: 40 - 55&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt; * Fourth set of threshold: 35 - 50&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt; * Fifth set of threshold: 37.5 - 52.5&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt; */&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzzRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;37.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzzPartialRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;52.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Next is to connect to our &lt;code class=&quot;language-text&quot;&gt;MongoDB&lt;/code&gt; client and starts doing some actual string comparisons. The actual code is pretty self-explanatory. All I did was to go through all the &lt;code class=&quot;language-text&quot;&gt;keyPhrases&lt;/code&gt;, compare it to the &lt;code class=&quot;language-text&quot;&gt;description&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;category&lt;/code&gt; using &lt;code class=&quot;language-text&quot;&gt;fuzzball&lt;/code&gt;. If it’s above the thresholds, return the &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; of the &lt;code class=&quot;language-text&quot;&gt;category&lt;/code&gt; then update the collection.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;4059028322894242300&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const fuzz = require(&apos;fuzzball&apos;);
const mongo = require(&apos;mongodb&apos;);

/**
 * First set of threshold: 55 - 70
 * Second set of threshold: 30 - 40
 * Third set of threshold: 40 - 55
 * Fourth set of threshold: 35 - 50
 * Fifth set of threshold: 37.5 - 52.5
 */
const fuzzRatio = 37.5;
const fuzzPartialRatio = 52.5;

const client = new mongo.MongoClient(&apos;mongodb://localhost:27017&apos;, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

const colName = &apos;eindescs_with_key_phrases&apos;;

client.connect(async err =&gt; {
  if (err) {
    console.log(&apos;error connecting to db&apos;, err);
    return;
  }

  const db = client.db(&apos;stl-health-hack&apos;);
  const keyPhrasesCol = db.collection(colName);
  const keyPhrases = await keyPhrasesCol.find({}).toArray();
  const categories = await db
    .collection(&apos;categories&apos;)
    .find({})
    .toArray();

  for (let i = 0; i &lt; keyPhrases.length; i++) {
    const keyPhrase = keyPhrases[i];

    const codes = categories
      .map(cat =&gt; {
        const originalString = keyPhrase.phrase_keys
          ? keyPhrase.phrase_keys.split(&apos;,&apos;).join(&apos; &apos;)
          : &apos;&apos;;
        const comparedString = cat.keywords.length
          ? cat.keywords.join(&apos; &apos;)
          : cat.description;

        const ratio = fuzz.ratio(
          originalString.toLowerCase(),
          comparedString.toLowerCase()
        );
        const partialRatio = fuzz.token_set_ratio(
          originalString.toLowerCase(),
          comparedString.toLowerCase(),
          { trySimple: true }
        );

        console.log(\`\${keyPhrase.EIN}\`, ratio, partialRatio);

        if (ratio &gt;= fuzzRatio &amp;&amp; partialRatio &gt;= fuzzPartialRatio) {
          return cat.code;
        }

        return &apos;&apos;;
      })
      .filter(c =&gt; !!c);

    await keyPhrasesCol.updateOne(
      { _id: keyPhrase._id },
      { \$set: { SERVICES: codes } }
    );
    console.log(\`Updated: \${keyPhrase._id}\`);
  }

  console.log(&apos;finished&apos;);
});`, `4059028322894242300`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzz &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fuzzball&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * First set of threshold: 55 - 70
 * Second set of threshold: 30 - 40
 * Third set of threshold: 40 - 55
 * Fourth set of threshold: 35 - 50
 * Fifth set of threshold: 37.5 - 52.5
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzzRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;37.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fuzzPartialRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;52.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; colName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;eindescs_with_key_phrases&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;error connecting to db&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; keyPhrasesCol &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; keyPhrases &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; keyPhrasesCol&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; categories &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; db
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;categories&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; keyPhrases&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; keyPhrase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; keyPhrases&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; codes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; categories
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; originalString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; keyPhrase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phrase_keys
          &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; keyPhrase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;phrase_keys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;,&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; comparedString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keywords&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length
          &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keywords&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ratio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fuzz&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ratio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          originalString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          comparedString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; partialRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fuzz&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;token_set_ratio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          originalString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          comparedString&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; trySimple&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;keyPhrase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ratio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; partialRatio&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ratio &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; fuzzRatio &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; partialRatio &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; fuzzPartialRatio&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; cat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; keyPhrasesCol&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; _id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; keyPhrase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SERVICES&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; codes &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Updated: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;keyPhrase&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;finished&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After this, we had pretty complete dataset, in our opinion. We’ve got &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;SERVICES&lt;/code&gt; at a pretty good point. But we’re still missing two key information: &lt;code class=&quot;language-text&quot;&gt;HOURS_OF_OPERATION&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt;. We got “some” of the &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt; from the &lt;code class=&quot;language-text&quot;&gt;XMLs&lt;/code&gt; but there were a lot more organizations that &lt;em&gt;DO NOT&lt;/em&gt; have their &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt; listed on their Tax Filing. Once again, we’re going to utilize &lt;code class=&quot;language-text&quot;&gt;Puppeteer&lt;/code&gt; for this task. The approach is pretty much the same as before, we’re just targeting different &lt;code class=&quot;language-text&quot;&gt;DOM Element&lt;/code&gt; to get what we want. The full script can be viewed below:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;82480413679435960000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const puppeteer = require(&apos;puppeteer&apos;);
const mongo = require(&apos;mongodb&apos;);
const { getHour } = require(&apos;./utils&apos;);

let result = 0;

const client = new mongo.MongoClient(&apos;mongodb://localhost:27017&apos;, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});

client.connect(err =&gt; {
  if (err) {
    console.log(err);
    return;
  }

  const db = client.db(&apos;stl-health-hack&apos;);
  const col = db.collection(&apos;queriedbmfs&apos;);

  col.find({}).toArray(async (err, bmfs) =&gt; {
    for (let i = 0; i &lt; bmfs.length; i++) {
      const bmf = bmfs[i];
      const { hours, phoneNum } = await getPhoneNumAndHours(bmf.NAME);

      const update = { \$set: {} };

      if (phoneNum) {
        update.\$set[&apos;PHONE_NUM&apos;] = phoneNum;
      }

      if (hours &amp;&amp; hours.length) {
        update.\$set[&apos;HOURS&apos;] = hours;
      }

      if (Object.keys(update.\$set).length) {
        await col.updateOne({ _id: bmf._id }, update);
        console.log(&apos;Done updated: &apos;, bmf._id);
        console.log(&apos;----------------------------------------&apos;);
      }
    }
  });
});

const getPhoneNumAndHours = async query =&gt; {
  console.log(&apos;----------------------------------------&apos;);
  console.log(\`Getting PhoneNumber and Hours for \${query}\`);
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto(&apos;https://google.com&apos;);

  await page.type(&apos;input.gLFyf&apos;, query);
  await page.keyboard.press(String.fromCharCode(13));
  await page.waitForNavigation();
  //   await page.waitForSelector(&apos;span[data-local-attribute=&amp;quot;d3ph&amp;quot;] &gt; span&apos;);
  await page.waitFor(2000);
  let phoneNum;
  let hours;

  const hasPhoneNode = await page.\$(&apos;span[data-local-attribute=&amp;quot;d3ph&amp;quot;] &gt; span&apos;);
  if (hasPhoneNode) {
    const phoneNumberNode = await page.\$eval(
      &apos;span[data-local-attribute=&amp;quot;d3ph&amp;quot;] &gt; span&apos;,
      el =&gt; el.textContent
    );
    console.log(\`Found PhoneNumber: \${phoneNumberNode}\`);
    phoneNum = phoneNumberNode
      .replace(&apos;(&apos;, &apos;&apos;)
      .replace(&apos;)&apos;, &apos;&apos;)
      .replace(/\s/, &apos;&apos;)
      .replace(&apos;-&apos;, &apos;&apos;);
  }

  const hoursNode = await page.\$(
    &apos;div[data-local-attribute=&amp;quot;d3oh&amp;quot;] div.h-n[jsaction=&amp;quot;oh.handleHoursAction&amp;quot;]&apos;
  );

  if (hoursNode) {
    hours = [];
    console.log(\`Found Hours\`);
    await page.click(
      &apos;div[data-local-attribute=&amp;quot;d3oh&amp;quot;] div.h-n[jsaction=&amp;quot;oh.handleHoursAction&amp;quot;]&apos;
    );
    const allHoursNodes = await page.\$\$(
      &apos;div[data-local-attribute=&amp;quot;d3oh&amp;quot;] div.a-h &gt; table &gt; tbody tr&apos;
    );

    for (let i = 0; i &lt; allHoursNodes.length; i++) {
      const node = allHoursNodes[i];
      const day = await node.\$eval(&apos;td.SKNSIb&apos;, el =&gt; el.textContent);
      const hour = await node.\$eval(&apos;td:last-of-type&apos;, el =&gt; el.textContent);
      hours.push({ day: day.toLowerCase(), hour: getHour(hour) });
    }
  }

  result++;
  console.log(\`Already ran \${result}\`);
  await page.close();
  await browser.close();
  return { phoneNum, hours };
};`, `82480413679435960000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; puppeteer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;puppeteer&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; getHour &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./utils&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb://localhost:27017&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; col &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bmfs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; bmf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; hours&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; phoneNum &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPhoneNumAndHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; update &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;phoneNum&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;PHONE_NUM&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; phoneNum&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hours &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; hours&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;HOURS&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; hours&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; _id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; update&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Done updated: &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;----------------------------------------&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;getPhoneNumAndHours&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;----------------------------------------&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Getting PhoneNumber and Hours for &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;query&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; browser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; puppeteer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;launch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; headless&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; page &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;goto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;https://google.com&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;input.gLFyf&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;keyboard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;press&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fromCharCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitForNavigation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;//   await page.waitForSelector(&apos;span[data-local-attribute=&quot;d3ph&quot;] &gt; span&apos;);&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; phoneNum&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; hours&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hasPhoneNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;span[data-local-attribute=&quot;d3ph&quot;] &gt; span&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hasPhoneNode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; phoneNumberNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&apos;span[data-local-attribute=&quot;d3ph&quot;] &gt; span&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Found PhoneNumber: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;phoneNumberNode&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    phoneNum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; phoneNumberNode
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;(&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;)&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;/\s/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;-&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hoursNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;div[data-local-attribute=&quot;d3oh&quot;] div.h-n[jsaction=&quot;oh.handleHoursAction&quot;]&apos;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hoursNode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    hours &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Found Hours&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;click&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&apos;div[data-local-attribute=&quot;d3oh&quot;] div.h-n[jsaction=&quot;oh.handleHoursAction&quot;]&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; allHoursNodes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$$&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&apos;div[data-local-attribute=&quot;d3oh&quot;] div.a-h &gt; table &gt; tbody tr&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; allHoursNodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; allHoursNodes&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; day &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;td.SKNSIb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hour &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$eval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;td:last-of-type&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;el&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      hours&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; day&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; day&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hour&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hour&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  result&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Already ran &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;result&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; page&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; phoneNum&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hours &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I had this script ran overnight as it’s running through all 2800+ organizations and it took about 4 hours to complete. Upon completion, we were able to get ~1400 more &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt; and ~700 more &lt;code class=&quot;language-text&quot;&gt;HOURS_OF_OPERATION&lt;/code&gt;. We’re happy with the amount of data we have gathered so far. Without further ado, we’ve started constructing the &lt;strong&gt;required data structure&lt;/strong&gt; and send a test request to check out our scores.&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;90313710064347550000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`/**
* The structure
* {
*   &amp;quot;team_id&amp;quot;: &amp;quot;our team id&amp;quot;,
*   &amp;quot;data&amp;quot;: {
*     [EIN]: {
*       name: {string} Organization name
*       hours: {
*         [sunday | monday | tuesday | wednesday | thursday | friday | saturday]: {
*           opens_at: {string} 24HR format - if closed, use 00:00
*           closes_at: {string} 24HR format - if opened 24hrs, use 24:00
*         }
*       }
*       url: {string} Organization URL
*       phone: {string} Organization Phone Number - US 10 digits
*       services: {Array&lt;string&gt;} A list of Service Codes
*     }
*   }
* }
*/

// Initialize a request JSON object
const reqJson = { team_id: &apos;&lt;our_team_id&gt;&apos;, data: {} };

// Connect to Mongo
client.connect(err =&gt; {
  if (err) return;
  console.log(&apos;connected&apos;);

  // Reference all needed database and collections
  const db = client.db(&apos;stl-health-hack&apos;);
  const col = db.collection(&apos;queriedbmfs&apos;);
  const einsWithCodes = db.collection(&apos;eindescs_with_key_phrases&apos;);

  einsWithCodes.find({}).toArray((err, einsWithCodes) =&gt; {
    col.find({}).toArray((err, docs) =&gt; {
      if (err) {
        console.log(err);
        return;
      }

      docs.forEach(doc =&gt; {
        // Grab the EIN
        reqJson.data[doc.EIN] = {
          name: doc.NAME
        };

        // If there&apos;s HOURS, grab the HOURS. getHours() is a function to clean-up hours gotten from Puppeteer Scraping
        if (doc.HOURS &amp;&amp; doc.HOURS.length) {
          console.log(doc.NAME, doc.HOURS);
          reqJson.data[doc.EIN][&apos;hours&apos;] = {
            sunday: getHours(&apos;sunday&apos;, doc.HOURS),
            monday: getHours(&apos;monday&apos;, doc.HOURS),
            tuesday: getHours(&apos;tuesday&apos;, doc.HOURS),
            wednesday: getHours(&apos;wednesday&apos;, doc.HOURS),
            thursday: getHours(&apos;thursday&apos;, doc.HOURS),
            friday: getHours(&apos;friday&apos;, doc.HOURS),
            saturday: getHours(&apos;saturday&apos;, doc.HOURS)
          };
        }

        // If there&apos;s WEBSITE, grab it
        if (
          doc.WEBSITE &amp;&amp;
          doc.WEBSITE !== &apos;N/A&apos; &amp;&amp;
          doc.WEBSITE !== &apos;NONE&apos; &amp;&amp;
          doc.WEBSITE !== &apos;None&apos;
        ) {
          reqJson.data[doc.EIN][&apos;url&apos;] = doc.WEBSITE;
        }

        // PHONE_NUM
        if (
          !!doc.PHONE_NUM &amp;&amp;
          doc.PHONE_NUM !== &apos;undefined&apos; &amp;&amp;
          doc.PHONE_NUM !== &apos;0&apos;
        ) {
          reqJson.data[doc.EIN][&apos;phone&apos;] = doc.PHONE_NUM;
        }

        // and Service Codes
        const foundCodes = einsWithCodes.find(ewc =&gt; ewc.EIN === doc.EIN)
          .SERVICES;
        if (foundCodes.length &amp;&amp; foundCodes.some(fc =&gt; fc.length &gt;= 3)) {
          reqJson.data[doc.EIN][&apos;services&apos;] = foundCodes.filter(
            fc =&gt; fc.length &gt;= 3
          );
        } else if (!!doc.NTEE_CD) {
          reqJson.data[doc.EIN][&apos;services&apos;] = [doc.NTEE_CD.substr(0, 3)];
        }

        eins.push(doc.EIN);
      });

      // Write the result to a file called request.json
      fs.writeFileSync(&apos;request.json&apos;, JSON.stringify(reqJson), {
        encoding: &apos;utf8&apos;
      });
      console.log(&apos;Finished&apos;);
    });
  });
});`, `90313710064347550000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
* The structure
* {
*   &quot;team_id&quot;: &quot;our team id&quot;,
*   &quot;data&quot;: {
*     [EIN]: {
*       name: {string} Organization name
*       hours: {
*         [sunday | monday | tuesday | wednesday | thursday | friday | saturday]: {
*           opens_at: {string} 24HR format - if closed, use 00:00
*           closes_at: {string} 24HR format - if opened 24hrs, use 24:00
*         }
*       }
*       url: {string} Organization URL
*       phone: {string} Organization Phone Number - US 10 digits
*       services: {Array&amp;lt;string&gt;} A list of Service Codes
*     }
*   }
* }
*/&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Initialize a request JSON object&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; reqJson &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; team_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;our_team_id&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Connect to Mongo&lt;/span&gt;
client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;connected&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Reference all needed database and collections&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; col &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; einsWithCodes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;eindescs_with_key_phrases&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  einsWithCodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; einsWithCodes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    col&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; docs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      docs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;doc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// Grab the EIN&lt;/span&gt;
        reqJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NAME&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// If there&apos;s HOURS, grab the HOURS. getHours() is a function to clean-up hours gotten from Puppeteer Scraping&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          reqJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;hours&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            sunday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sunday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            monday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;monday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            tuesday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tuesday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            wednesday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;wednesday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            thursday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;thursday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            friday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;friday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            saturday&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getHours&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;saturday&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;HOURS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// If there&apos;s WEBSITE, grab it&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;N/A&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;NONE&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;None&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          reqJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;url&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;WEBSITE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// PHONE_NUM&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PHONE_NUM&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PHONE_NUM&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;undefined&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
          doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PHONE_NUM&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0&apos;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          reqJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;phone&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PHONE_NUM&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// and Service Codes&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; foundCodes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; einsWithCodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ewc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; ewc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SERVICES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;foundCodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; foundCodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; fc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          reqJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;services&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; foundCodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;token parameter&quot;&gt;fc&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; fc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          reqJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;services&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

        eins&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;// Write the result to a file called request.json&lt;/span&gt;
      fs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;writeFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;request.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reqJson&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        encoding&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;utf8&apos;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Finished&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After we got our &lt;code class=&quot;language-text&quot;&gt;request.json&lt;/code&gt;, we sent that in a request right away. Our scores was, well, &lt;strong&gt;negative&lt;/strong&gt; 🙀. However, the organizers did mention that the scores during the test runs are nothing but a mere measurement for teams to try to improve, but ultimately they do not contribute to final judging, which was a really good thing for us. It’s already day 3 when we’ve got to this time of the Hackathon. We felt like we’ve done everything we could in the amount of time we had so we “called it”. Personally, I was pretty &lt;em&gt;pissed&lt;/em&gt; about how my &lt;strong&gt;AWS&lt;/strong&gt; account needed 24-hour to verify to be able to use &lt;strong&gt;AWS Comprehend&lt;/strong&gt;. That’s one of the reasons that kind of set our team back on the &lt;strong&gt;Comprehend&lt;/strong&gt; part of the Hack. However, on the last day, I’ve tried using &lt;strong&gt;Comprehend&lt;/strong&gt; with a different approach:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Still use &lt;code class=&quot;language-text&quot;&gt;categories&lt;/code&gt; for its &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;keywords&lt;/code&gt;. But, I flatten the &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;keywords&lt;/code&gt; so that each &lt;code class=&quot;language-text&quot;&gt;code&lt;/code&gt; will have multiple records, each record will be correspond to a single &lt;code class=&quot;language-text&quot;&gt;keyword&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/be88773529263f8bc15a307a4eb6ca41/dc666/keywords_and_codes.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 115.00000000000001%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAXCAYAAAALHW+jAAAACXBIWXMAABYlAAAWJQFJUiTwAAAC4klEQVQ4y42V6XbaQAyFeY82hQBeMd5nbGO2kK3v/0Kq7h3bdVKS0x86mjGez5KuNCy8JBI/2kqcxlL0naSmkry1tKRMZestxfNX6ldccx+sxQ/v28JPd/rCo9SdlePvd7HnXprrSeypF3PUD5SJFLaglU0lhVocbyUMVhKGjx9Nny28Edi30r+9Kewsla7r44FmTrBe7OUkWZ1LWiQ87HsP4vu/nHnOB/p84Wdz4CuBABiNFL7WMtjLUSrNIMki2ecxfValut7xAzA8DxhhljjgoZHDy7NU6hnlwdK3T1c5vL6ov2jEnRyGj5atkdwUkmvUeLew5QyoxUSEODhGCg/4mC7WVd8wckS72wcEIHVv+5MepfgIVBBq1t6uLu2TOzyHI0q8A79LQ0JDPQ8YI/T3kaa8cpG9v08vI0VEhn3Z1g6qcBet1lNhEGIEjUovvFx7LdyIIfCNaaEeBirrMwC511RRz6zOJtBn2JQygBClU1GQbqPRNdeL7m+EAuTUPjHK4F4PjsB1034QBYdZP41wVBYW7zwJ/OUEg78HXmxMraO15FRAlFGQsjNufXYqU1V976tUZ0DLWa2HGiIqQJyavTZwNkHZa1OU66+AZqayAm9PbBF7PhKC57Dc5NM+yWLxNj+msfO2D+xDts3GugiZMmqowHH8AMBlgdSx7p5v7neIpoaywNhq+qE48RVY1y5lqKwHkCqA8EVT86tx4mnfRRLpLRPFGwqEpkZdYYgYfRlG60Hl4XLonp+cqrrGrHJGFYoo0H+oIa4v1BWXA5XWmrpbZzmkPNSQlwL770xgYSumiSkBDIARmpZ7SXX/rShzIAQBCGtcS0iFFwBFeJjEmPfk38a2jWtsTW8sfjPMMYCoKz4Q7bbuEv3Uf/+MHlWONjpSZoK4VumYHpVGD2rtUHyA/2/0hgsVI8c+HHoOs4v0AcRvUHM+Mfdr6K+oKNuG/yfdFO1er3fXtMsv6za3P3qrzW47xChxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;keywords_and_codes&quot;
        title=&quot;keywords_and_codes&quot;
        src=&quot;/static/be88773529263f8bc15a307a4eb6ca41/1bed9/keywords_and_codes.png&quot;
        srcset=&quot;/static/be88773529263f8bc15a307a4eb6ca41/7b64c/keywords_and_codes.png 160w,
/static/be88773529263f8bc15a307a4eb6ca41/4e610/keywords_and_codes.png 320w,
/static/be88773529263f8bc15a307a4eb6ca41/1bed9/keywords_and_codes.png 640w,
/static/be88773529263f8bc15a307a4eb6ca41/dc666/keywords_and_codes.png 786w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;something like this&lt;/em&gt;&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Feed the &lt;code class=&quot;language-text&quot;&gt;CSV&lt;/code&gt; to &lt;strong&gt;Comprehend&lt;/strong&gt; to start training it. My hope was when I input a &lt;code class=&quot;language-text&quot;&gt;keyword&lt;/code&gt;, &lt;strong&gt;Comprehend&lt;/strong&gt; might be able to suggest a list of services that are close to the input &lt;code class=&quot;language-text&quot;&gt;keyword&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Put the result back in &lt;strong&gt;Mongo&lt;/strong&gt; and work on some aggregations to get more meaningful, and hopefully more accurate data on what services an organization provides.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/c76032da63d568b09246c0ad954008a0/b3373/eins_codes.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 142.5%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAdCAYAAACqhkzFAAAACXBIWXMAABYlAAAWJQFJUiTwAAADYklEQVRIx5VV2ZLbOAz0//9bHrKVZB+StazDh6ybEkmROnoBSJYdZ2Y8URWKlEiCDaDR2sXXBpXSKBuyusMlV8jKVuZN19NciRX0rvsR1s+wbpLR0Phsu31yRRjFOBxC7PcBgugo71Gc4JrlMg9oja3tNGzfixlr4fywmWcbRuzOlyuiKMLxdELbdmJlWaMoCjRKoW4aeq+gVIe6bpBlhazz2HUWxjiyHlobdFpj13YGeZbRBw1+tC3Q+wbejqiyGnVeoyoz1G1CKTiRHSn8Pao2pjSFKMQCQtxgHAmhYod5Buc8Zkw4Zz/owIFuq5AXMdIsQFr8Wg94Cqsns6vd5+M4YJ7nBWF6uWwIe6dRNWdKvJJN0zTJ92GiA3j9CELOl3NOPszrKb71lH2D0ld4Zykt/8LUCTCN4pjRvGXikBH2VDmsG3nO6IytYPoG0+ABQj63Kebhvu9NhDVVL4njzSGHaIkSEyHxg6GDkxy2NB/XQ+85Wxw2LZIkJh552XjLWe87ROcvVMEIru9Qpd9gs5/A6LeQ33HYIY4jyeEtD1yg25yRznwJnx9ozzS+DpkdPobMaAfKleou1AUGA6FShqg1uM3Ze0HvKgo5ju8hL6jmtcrfqc+PVGUDWx7g8/8we/sCITk8HhNCNGzobs7xQI8lcdNWpO37k3NBeDgE1JedtM6tKJ95OPA/eMgOb7RhlAM55bkVNXGkLBbaaFETXuc1blNre7yVyDWHERpSFQ7VuZ7QKlGd3ngY0sSu1eRUiam2pD6vaazWgvXCV+7zDeFCGy83VComIaVWtAMuxwjX8xHpNUSpIql6052JmwdRn5I4ypbXlDJdYmQ95KKE4YFCcaI21/IXqctPtJolK0WtLuiIMvM0fyqngjAMwwceksxbLTzUtqZxQd6RTvrR/Vb5Z7vnkBT7ufWc10jSrxRqLK1Xk9pI63G3fKQ27DDY70kH77czhe4cm+4848S/bL2tKG5rvYGSy9XjLuldK1JWtycSDPO51uOfFHPsufXO+Q/6d9xaL1ha76UePiC8OXwM+c1qfqSHksNg/1vITJGlKP8Q71JaMyiJSpZoJP38EcJqFdjHkHnOzGcuavoNjFxZU2FS59chLzkMBSGjW8YRz/vnvwv5rjYbXTB/SOD3nP4PsHjUeoONXwEAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;eins_codes&quot;
        title=&quot;eins_codes&quot;
        src=&quot;/static/c76032da63d568b09246c0ad954008a0/1bed9/eins_codes.png&quot;
        srcset=&quot;/static/c76032da63d568b09246c0ad954008a0/7b64c/eins_codes.png 160w,
/static/c76032da63d568b09246c0ad954008a0/4e610/eins_codes.png 320w,
/static/c76032da63d568b09246c0ad954008a0/1bed9/eins_codes.png 640w,
/static/c76032da63d568b09246c0ad954008a0/7d769/eins_codes.png 960w,
/static/c76032da63d568b09246c0ad954008a0/b3373/eins_codes.png 1070w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;I was able to get to this but ran out of time and couldn’t work on any aggregation&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;presentation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#presentation&quot; aria-label=&quot;presentation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Presentation&lt;/h3&gt;
&lt;p&gt;Our team was 7th on the list of teams to present. It was nerve wrecking, even more so after listening to other teams. There were so many good approaches that we could have taken. Most of the teams struggled with the same problems:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Data is messy or not able to understand the data fully&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS Comprehend&lt;/strong&gt; comprehension?! &lt;/li&gt;
&lt;li&gt;Consolidating/Centralizing the data&lt;/li&gt;
&lt;li&gt;Other 3rd party APIs limitation, like &lt;code class=&quot;language-text&quot;&gt;Google Places API&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Our team came up to present. We talked about what we did, what problems we faced. We discussed what we could have done earlier and answered judges’ questions. I think we did pretty good but I honestly think we wouldn’t place at all because there were so many good teams. There were even some really good one-man team. But against all odds, our team places &lt;strong&gt;2nd&lt;/strong&gt; for utilizing &lt;code class=&quot;language-text&quot;&gt;fuzzywuzzy&lt;/code&gt;. As soon as I heard that, I jumped out of my seat, started approaching my teammates and celebrating 🎉. Through this Hackathon, I’ve learned so much more about both on personal level and social level. I learned that there are so many people out there that are lacking accesses to the essentials like Medical and Health Services and I did feel like what all participants have done over the weekend was tremendously meaningful to the society as a whole. Personally, I learned a couple more technologies and earned myself a couple more friends. And I’d say that’s a win-win-win-win-win-win 🎊. &lt;/p&gt;
&lt;p&gt;Thank you all for going along this far. I know it’s all technical stuffs, code stuffs but it’s literally what we did, we code. And I loved explaining the meanings behind all those lines of code to all of you who’re interested. I’ve also pushed our project on &lt;a href=&quot;https://github.com/nartc/stl-healh-equity-hack&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Github&lt;/a&gt;. Please feel free to reach out to me if you have further questions or discussions. You can always get in touch with me on my social medias. Until next time 👋&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Slalom Health Equity Hackathon - Part 1]]></title><description><![CDATA[This is Part One of a two-part series about my journey through Slalom Health Equity Hackathon. You can read about Part Two here. Over the…]]></description><link>https://nartc.netlify.com/blogs/slalom-health-equity-hackathon-1/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/slalom-health-equity-hackathon-1/</guid><pubDate>Sun, 08 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This is &lt;strong&gt;Part One&lt;/strong&gt; of a two-part series about my journey through &lt;strong&gt;Slalom Health Equity Hackathon&lt;/strong&gt;. You can read about &lt;strong&gt;&lt;a href=&quot;/blogs/slalom-health-equity-hackathon-2&quot;&gt;Part Two&lt;/a&gt;&lt;/strong&gt; here.&lt;/p&gt;
&lt;p&gt;Over the past weekend, I was participating in &lt;strong&gt;Health Equity Hackathon&lt;/strong&gt; which was hosted and organized by &lt;strong&gt;&lt;a href=&quot;https://www.slalom.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Slalom&lt;/a&gt;&lt;/strong&gt;, partnered with &lt;strong&gt;&lt;a href=&quot;https://stl.hellocovo.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Covo&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href=&quot;https://www.johego.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Johego&lt;/a&gt;&lt;/strong&gt;, and sponsored by &lt;strong&gt;&lt;a href=&quot;https://aws.amazon.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;AWS&lt;/a&gt;&lt;/strong&gt;. And it was a blast 🚀 !&lt;/p&gt;
&lt;p&gt;Personally, I wasn’t planning on take part in the Hackathon at first. But I changed my mind immediately when I read the more about the Hack, which I’ll elaborate more down below. One of the reasons that I was hesitant to join in the beginning was because my ”&lt;em&gt;usual hack-mates&lt;/em&gt;” were busy (&lt;em&gt;At least, that’s what I thought through our daily chat&lt;/em&gt;). When I decided to participate, I joined by myself and hoped to get in a team during &lt;strong&gt;Team Formation&lt;/strong&gt; session of the Hack. Here’s how it went.&lt;/p&gt;
&lt;h3 id=&quot;the-challenge&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-challenge&quot; aria-label=&quot;the challenge permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Challenge&lt;/h3&gt;
&lt;p&gt;The Hack started off by an organizer from &lt;strong&gt;Slalom&lt;/strong&gt;, Tara Nesbitt, giving her presentation about the Hack’s guidelines and purposes. Next up was &lt;strong&gt;Johego&lt;/strong&gt; Founder and CEO, Michael Kehoe. Michael was introducing &lt;strong&gt;Johego&lt;/strong&gt; and explaining why he does what he’s doing and the positive impact of the work that his team at &lt;strong&gt;Johego&lt;/strong&gt; is doing, as well as all the Hack’s participants were willing to sign their weekends up to contribute to the same positivity.&lt;/p&gt;
&lt;p&gt;The problem statement sounds simple enough, at least to me: Medical and Health Services Accessibility for everyone. Sounds simple right? Medical and Health services are essential things that everyone should have access to, easily. Well, unfortunately that’s not the case. According to Michael, the average amount of time that a person gets connected to the right resource for their medical and health need is &lt;strong&gt;43 minutes/resource&lt;/strong&gt;. Michael also gave a clear example on how we could access to movie tickets via &lt;strong&gt;Fandango&lt;/strong&gt; in a matter of minute. Why can’t we do the same for Medical? The reason, mainly, is how scattered the data is and how expensive it is to validate data on Medical.&lt;/p&gt;
&lt;p&gt;Michael founded &lt;strong&gt;Johego&lt;/strong&gt; with the purpose of closing the gap of &lt;strong&gt;Medical Accessibility&lt;/strong&gt; and by participating in this Hackathon, I feel like everyone wants to contribute to the same purpose.&lt;/p&gt;
&lt;p&gt;This Hackathon was a little bit different than the ones that I’ve done before. When I think about Hackathons, I think about making an &lt;em&gt;Application&lt;/em&gt; that has an impact on one or more aspects of the Problem Statement. The deliverable has been always something visible, and, for lack of better words, presentable. In contrast, participants were given raw datasets and were asked to analyze, filter, and augment the raw provided datasets by using different tools and especially, with the power of &lt;strong&gt;Natual Language Processing&lt;/strong&gt; by utilizing &lt;strong&gt;AWS Comprehend&lt;/strong&gt;. This was also the main reason that changed my mind about joining the Hack. I was both surprised and excited for being able to finally learn something about data and Machine Learning. Problem statement’s provided. Next, I needed a team.&lt;/p&gt;
&lt;h3 id=&quot;the-team&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-team&quot; aria-label=&quot;the team permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Team&lt;/h3&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2bd5942b294ba1debcc00a3d7be5477c/5fd6b/team.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAECBP/EABYBAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABx2qzbGH/xAAZEAEBAQADAAAAAAAAAAAAAAABAgMAERP/2gAIAQEAAQUCbeyKoLuzK5zaPSgDn//EABYRAQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAwEBPwFsf//EABURAQEAAAAAAAAAAAAAAAAAAAAh/9oACAECAQE/AVf/xAAdEAABBAIDAAAAAAAAAAAAAAABAAIRIRBBIjFS/9oACAEBAAY/AmnaJjhsqyBFdK2yF5Bx/8QAGRABAQEBAQEAAAAAAAAAAAAAAREAMUFx/9oACAEBAAE/IXAnRDzNWLiPMKYyCuaTsdHXGUdMRDnwd//aAAwDAQACAAMAAAAQRN//xAAWEQEBAQAAAAAAAAAAAAAAAAABIRD/2gAIAQMBAT8QY3H/xAAWEQADAAAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8QET//xAAeEAEAAgIBBQAAAAAAAAAAAAABESEAMUFRYYGRsf/aAAgBAQABPxAkZ4waPN7yD6KSI5od2cYFhIyU19yEtdqU6X2cd7YF8NYzltUo9pn/2Q==&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;team&quot;
        title=&quot;team&quot;
        src=&quot;/static/2bd5942b294ba1debcc00a3d7be5477c/bbe0c/team.jpg&quot;
        srcset=&quot;/static/2bd5942b294ba1debcc00a3d7be5477c/f7be0/team.jpg 160w,
/static/2bd5942b294ba1debcc00a3d7be5477c/b4845/team.jpg 320w,
/static/2bd5942b294ba1debcc00a3d7be5477c/bbe0c/team.jpg 640w,
/static/2bd5942b294ba1debcc00a3d7be5477c/5fd6b/team.jpg 800w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;behind the scene&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I was able to join a team that was consisted of 3 amazing people: Mar, Vanessa and Alex. A friend of mine introduced me to Mar and I’ve decided to join with Mar because I liked his personality when he approached me. Mar and Vanessa were very energetic and welcoming which made me feel really nice about the team. Alex didn’t show up on the first day but we ”&lt;em&gt;communicated&lt;/em&gt;” briefly during the first night through &lt;strong&gt;Slack&lt;/strong&gt; and I thought this guy was smart and knew what he’s doing, and I was excited to meet him.&lt;/p&gt;
&lt;p&gt;Next morning, I got to meet Alex and the guy was like I thought he was, a smart guy. We immediately started working on the project and discussed about how we interpreted the data along the way. It was such a fun experience working with these guys. And it was rewarding, as we finished the Hack with the &lt;strong&gt;2nd place&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/08bc92f70c22133da46cb414667864b5/e4105/hack_win.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 75%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIEBf/EABUBAQEAAAAAAAAAAAAAAAAAAAEC/9oADAMBAAIQAxAAAAHQnneXREB//8QAGxAAAgIDAQAAAAAAAAAAAAAAAgMAAQQREyT/2gAIAQEAAQUCYwVwsgag6Icm/WTitKN8f//EABURAQEAAAAAAAAAAAAAAAAAAAAS/9oACAEDAQE/AaU//8QAFREBAQAAAAAAAAAAAAAAAAAAABL/2gAIAQIBAT8BlL//xAAcEAACAwADAQAAAAAAAAAAAAAAAQIRMQMSQeH/2gAIAQEABj8CS9eI+CksZxddopxTtEL2j//EABoQAQEBAAMBAAAAAAAAAAAAAAERABAhMUH/2gAIAQEAAT8heduyxBI/fWVQhS5iToPc7oKl4Kf/2gAMAwEAAgADAAAAEFQf/8QAFhEBAQEAAAAAAAAAAAAAAAAAABFR/9oACAEDAQE/EMKf/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8QhD//xAAdEAACAwACAwAAAAAAAAAAAAABEQAhMUFRcZGh/9oACAEBAAE/EGGnyWHpWQPQjajtdVHkqARXiHwCR4slQisGZEX1R+6+T//Z&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;Hackathon Win&quot;
        title=&quot;Hackathon Win&quot;
        src=&quot;/static/08bc92f70c22133da46cb414667864b5/bbe0c/hack_win.jpg&quot;
        srcset=&quot;/static/08bc92f70c22133da46cb414667864b5/f7be0/hack_win.jpg 160w,
/static/08bc92f70c22133da46cb414667864b5/b4845/hack_win.jpg 320w,
/static/08bc92f70c22133da46cb414667864b5/bbe0c/hack_win.jpg 640w,
/static/08bc92f70c22133da46cb414667864b5/18e3b/hack_win.jpg 960w,
/static/08bc92f70c22133da46cb414667864b5/38ece/hack_win.jpg 1280w,
/static/08bc92f70c22133da46cb414667864b5/e4105/hack_win.jpg 3512w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;The check though 🤑&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&quot;what-we-did&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#what-we-did&quot; aria-label=&quot;what we did permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;What We Did&lt;/h3&gt;
&lt;p&gt;The main purpose of this blog was to brag. No, not really 😛. I’m writing this blog post to share with all of you how our team contributed to the goal of the Hackathon’s organizers, partners, and sponsors.&lt;/p&gt;
&lt;p&gt;A fast rundown of all the technologies/tools we used in the Hack:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.mongodb.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;MongoDB&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://aws.amazon.com/comprehend/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;AWS Comprehend&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://nodejs.org/en/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;NodeJS&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/GoogleChrome/puppeteer&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Puppeteer - Headless Chrome API&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://aws.amazon.com/sdk-for-node-js/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;AWS SDK for NodeJS&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.python.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Python&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://jupyter.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Jupyter&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://boto3.amazonaws.com/v1/documentation/api/latest/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Boto3&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://code.visualstudio.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;VSCode&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://nosqlbooster.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;NoSQL Booster for MongoDB&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.getpostman.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Postman&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After we get the data from the organizers, the first thing we did was to figure out how to store this data in a place where we can work and continue working on it for the next 2 days. That’s why I suggested that we should store the data in &lt;strong&gt;MongoDB&lt;/strong&gt;. The main reason is because &lt;strong&gt;MongoDB&lt;/strong&gt; is a &lt;strong&gt;NoSQL&lt;/strong&gt; database and a &lt;em&gt;schema-less&lt;/em&gt; database solution is great for situations like the challenge of this Hackathon. We only need a place to jot all the data down without worrying about what shape the data is. With that in mind, I quickly got all the &lt;strong&gt;CSV&lt;/strong&gt; and &lt;strong&gt;JSON&lt;/strong&gt; files that were provided and imported them in my local &lt;strong&gt;MongoDB&lt;/strong&gt; instance using &lt;strong&gt;NoSQL Booster&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All data provided was in &lt;strong&gt;CSV&lt;/strong&gt; format or &lt;strong&gt;JSON&lt;/strong&gt; format. It was funny because I didn’t have any tools on my machine that read CSV 🤧 so I had to use &lt;strong&gt;Postman&lt;/strong&gt; to fetch the data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dc16db402bed7bb090a65a0fa8bcb2ba/76b06/db.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 85.625%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACOklEQVQ4y5VUyY7aQBTk/++5zDkXMklIlFxySI5RJBQGbLx223gDjM1ik4AXoCvPjRgRZmNaKrfklsuv3qvqVlUWGBgc3TsFYeCDOw48z4Pv+1iv1yiKAs0SQki8tFricECyWMJ0PJg2g2EYcF0Xuq4jjmNJeiK8ZrWax2G/hz9NoBOhogygqKokns1mSJIEezq/llQS1nUN5o+hWYyqc2RlURRhs9nIswOpeDWhG05lhcy2JVlTXZZl2O12r5e8I0IeTGBxFwb1Tie5YRhK0vMeXuKxHxGhQF2V8MYxLMZhGjosy8RkHGGeJijL4olaGlJqxQWOkqnnbpRQD12oQwvcDZAucoynKbJ1gW15wGK1kdiWApvtHntxor2U/Oc36lUX3qgHffANVu8W1t1H2P0ORtpXcOUzAuMLfK0Dj5BFP7AKv6Ne/gL+9iDoe5yhhbSNenqLkfMTw+5bhP038Ps3CAY3yL02ykkHIv0ArD8BOWHx/oj0HUTSlnvDccJR8k5gNJ5BNWxouol4Nsc0Tsg+KYqyJuxR1QLV7ihRnEl9KJlenaaskw8dh9NQLJimKdOiaRrZKERKA8pWq/9jeLafcO9Dh3yo6AZsm4bCuQRjtrRPY508zx/m+hHcE46iKUzmgDOG5XIpUyJjSSk599pLBj8jjKGZNiySqg6HMstNjufzObbb7bNmfjJ6Kg3ENA2odDk0fWzkMqo4TVOJqqquJwzotrG4Q5XpYNS/FQ2giV5zdlnZc4T/ACvTEDbggRv3AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;database&quot;
        title=&quot;database&quot;
        src=&quot;/static/dc16db402bed7bb090a65a0fa8bcb2ba/1bed9/db.png&quot;
        srcset=&quot;/static/dc16db402bed7bb090a65a0fa8bcb2ba/7b64c/db.png 160w,
/static/dc16db402bed7bb090a65a0fa8bcb2ba/4e610/db.png 320w,
/static/dc16db402bed7bb090a65a0fa8bcb2ba/1bed9/db.png 640w,
/static/dc16db402bed7bb090a65a0fa8bcb2ba/76b06/db.png 854w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;my final local MongoDB instance&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Out of all 5 datasets that were provided, the biggest one has 450k rows of data which was a pain in the butt to work with. We didn’t really bother indexing any of the imported data due to time constraint of a hackathon format. Once all the data was imported, I started to run through the Documentation that &lt;strong&gt;Johego&lt;/strong&gt; put together as to how to filter the data and came up with the following fundamental criteria:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I only want the Organizations that have matching &lt;strong&gt;EIN&lt;/strong&gt; (&lt;em&gt;a unique ID to Organization in IRS data&lt;/em&gt;) with the ones in &lt;strong&gt;Tax Filings 2018&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Each organization provides activities/services to the community and this information is captured by annotating the services by &lt;strong&gt;Activity Codes&lt;/strong&gt; and/or &lt;strong&gt;NTEE Codes&lt;/strong&gt; (&lt;em&gt;based on when the organization was established. To my understanding, Activity Codes are old format&lt;/em&gt;). &lt;strong&gt;Johego&lt;/strong&gt; only cares about a specific subset of &lt;em&gt;Services&lt;/em&gt; Codes and also provides the participants all the &lt;strong&gt;Whitelisted Codes&lt;/strong&gt; so I only want the Organizations that have &lt;em&gt;Services&lt;/em&gt; code in the range of the &lt;strong&gt;Whitelisted Codes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;The Organizations dataset do not come with the &lt;strong&gt;Filings XML&lt;/strong&gt; file that will provide us more information about the Organization: &lt;strong&gt;Phone Number&lt;/strong&gt; and &lt;strong&gt;Website&lt;/strong&gt;. So I also need to make sure to add the &lt;strong&gt;Filings XML URL&lt;/strong&gt; to my &lt;em&gt;enhanced&lt;/em&gt; Organizations dataset.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With all 3 above things in mind, I started writing my queries against all the provided datasets.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The first query is pretty simple. All I did was read two collections: &lt;code class=&quot;language-text&quot;&gt;bmfs&lt;/code&gt; (36K rows) and &lt;code class=&quot;language-text&quot;&gt;filings&lt;/code&gt; (450k rows) and match all the &lt;strong&gt;EINs&lt;/strong&gt; between the two.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;16473187007397573000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const filings = db.filings.find({});

db.bmfs.find({}).forEach((doc) =&gt; {
  const found = filings.find(f =&gt; f.EIN === doc.EIN);
  if (found) {
    // if have matching EIN, grab the XML URL from Filings Index and save that onto the document.
    db.bmfs.updateOne({_id: doc._id}, {\$set: {URL: found.URL}});
  } else {
    // if not match, remove the document from the collection.
    db.bmfs.deleteOne({_id: doc._id});
  }
});`, `16473187007397573000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; filings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; found &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; filings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; f&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// if have matching EIN, grab the XML URL from Filings Index and save that onto the document.&lt;/span&gt;
    db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// if not match, remove the document from the collection.&lt;/span&gt;
    db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After this query is ran, I got the &lt;code class=&quot;language-text&quot;&gt;bmfs&lt;/code&gt; from 36K rows down to 8k rows, which means we have 8k organizations that have matching &lt;strong&gt;EINs&lt;/strong&gt; with the &lt;strong&gt;Filings Index&lt;/strong&gt;, and at the same time, I could update the &lt;code class=&quot;language-text&quot;&gt;bmfs&lt;/code&gt; with matching &lt;code class=&quot;language-text&quot;&gt;XML URL&lt;/code&gt; as well. This is a beauty of &lt;strong&gt;MongoDB&lt;/strong&gt;. &lt;strong&gt;(1)&lt;/strong&gt; and &lt;strong&gt;(3)&lt;/strong&gt; were taken care of.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;
&lt;p&gt;Next query is a bit more complicated and composed of multiple steps. The requirement is straightforward but the provided data is a bit messup. Again, I’ll run down what happens:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each Organization has a field called &lt;strong&gt;ACTIVITY&lt;/strong&gt; and/or &lt;strong&gt;NTEE_CD&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The whitelisted Activities is a collection of 3-digit codes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ACTIVITY&lt;/strong&gt; fields among all Organizations were not consistent. The max-length is 9 characters (which is 3 Activities at the most) but some &lt;strong&gt;ACTIVITY&lt;/strong&gt; fields were missing 0s because of the way data is handled from one medium to another, 0s are missing.&lt;/li&gt;
&lt;li&gt;If an Organization has EITHER matching &lt;strong&gt;ACTIVITY&lt;/strong&gt; with the Whitelisted OR matching &lt;strong&gt;NTEE_CD&lt;/strong&gt; with the Whitelisted codes, then it should be included.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With all of these information, my first step was to clean up the &lt;code class=&quot;language-text&quot;&gt;bmfs&lt;/code&gt; collection.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Get all &lt;code class=&quot;language-text&quot;&gt;bmfs&lt;/code&gt; that have &lt;strong&gt;ACTIVITY&lt;/strong&gt; field and its value is not &lt;code class=&quot;language-text&quot;&gt;&amp;quot;0&amp;quot;&lt;/code&gt;. If the &lt;strong&gt;ACTIVITY&lt;/strong&gt; length is less than 9, then prepend 0s to it to make it 9 characters.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;6999377204733249000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`db.bmfs.find({ACTIVITY: {\$ne: &amp;quot;0&amp;quot;}}).forEach((doc) =&gt; {
  if (doc.ACTIVITY.length &lt; 9) {
    // If ACTIVITY length is less than 9, then make an array of length: 9 - length 
    // fill that array with 0, 
    // join the array of 0s 
    // concat the current ACTIVITY

    // Eg: ACTIVITY.length is 2. Then an array of [&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;] is needed.
    // [&amp;quot;0&amp;quot;, &amp;quot;0&amp;quot;].join(&amp;quot;&amp;quot;) =&gt; &amp;quot;00&amp;quot;
    // &amp;quot;00&amp;quot;.concat(&amp;quot;1234567&amp;quot;) =&gt; &amp;quot;001234567&amp;quot;
    doc.ACTIVITY = Array.from({length: 9 - doc.ACTIVITY.length}).fill(&amp;quot;0&amp;quot;).join(&amp;quot;&amp;quot;).concat(doc.ACTIVITY);
    
    // Then update the document with the prepended ACTIVITY
    db.bmfs.updateOne({_id: doc._id}, {\$set: {ACTIVITY: doc.ACTIVITY}});
  }
})`, `6999377204733249000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$ne&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// If ACTIVITY length is less than 9, then make an array of length: 9 - length &lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// fill that array with 0, &lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// join the array of 0s &lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// concat the current ACTIVITY&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Eg: ACTIVITY.length is 2. Then an array of [&quot;0&quot;, &quot;0&quot;] is needed.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// [&quot;0&quot;, &quot;0&quot;].join(&quot;&quot;) =&gt; &quot;00&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// &quot;00&quot;.concat(&quot;1234567&quot;) =&gt; &quot;001234567&quot;&lt;/span&gt;
    doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;length&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Then update the document with the prepended ACTIVITY&lt;/span&gt;
    db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Now that I’ve got the &lt;strong&gt;ACTIVITY&lt;/strong&gt; cleaned up, I thought that it might be easier to compare if the &lt;strong&gt;ACTIVITY&lt;/strong&gt; were in a form of Array of 3 3-digit code. Eg: &lt;code class=&quot;language-text&quot;&gt;[&amp;quot;123&amp;quot;, &amp;quot;456&amp;quot;, &amp;quot;789&amp;quot;]&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;&amp;quot;123456789&amp;quot;&lt;/code&gt;. So I did exactly that, make &lt;strong&gt;ACTIVITY&lt;/strong&gt; into an array of 3-digit codes.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;45503526361718220000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`db.bmfs.find({ACTIVITY: {\$ne: 0}}).forEach((doc) =&gt; {
  // initialize an empty array
  const codes = [];
  
  // create a loop that will loop 3 times
  for (let i = 0; i &lt; 3; i++) {
    // each time, get a substring of the ACTIVITY in length of 3 and push that to codes array
    // eg: first iteration, i = 0, get the substring from index 0 (i * 3) and take 3 characters. So 123456789.substr(0, 3) gives me 123
    // second iteration, i = 1, continue getting the substring from index 3 and take 3 chars. So 123456789.substr(3, 3) gives me 456
    // same for last iteration.  
    codes.push(doc.ACTIVITY.substr(i * 3, 3));
  }
  // Update the document with the codes array.
  db.bmfs.updateOne({_id: it._id}, {\$set: {ACTIVITY_CODES: codes}});
})`, `45503526361718220000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$ne&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// initialize an empty array&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; codes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;// create a loop that will loop 3 times&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// each time, get a substring of the ACTIVITY in length of 3 and push that to codes array&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// eg: first iteration, i = 0, get the substring from index 0 (i * 3) and take 3 characters. So 123456789.substr(0, 3) gives me 123&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// second iteration, i = 1, continue getting the substring from index 3 and take 3 chars. So 123456789.substr(3, 3) gives me 456&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// same for last iteration.  &lt;/span&gt;
    codes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Update the document with the codes array.&lt;/span&gt;
  db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY_CODES&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; codes&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;You can see that I could have combined the two previous queries but because I didn’t realize I needed the &lt;strong&gt;CODES&lt;/strong&gt; until later.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Now I have &lt;strong&gt;ACTIVITY&lt;/strong&gt;, &lt;strong&gt;ACTIVITY_CODES&lt;/strong&gt; and &lt;strong&gt;NTEE_CD&lt;/strong&gt; all good to go. Time to actually filter the Organizations.&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;97517900153677200000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Initialize an empty array
const result = [];

// This is just to be safe, I drop the collection before running this script.
db.queriedbmfs.deleteMany({});

// Grab all the Whitelisted Codes
const codes = db.activitycodes.find({});

// Grab all the whitelisted NTEEs
const ntees = db.ntees.find({});

// Since my whitelisted codes are both MongoDB Collection
// so they come back with a form of Array of Object with _id and the actual code.
// I only want the Array of codes so I run them both through .map() method to grab the code.
const codesArr = codes.map(c =&gt; c.code);
const nteesArr = ntees.map(n =&gt; n.code);

// Filter the bmfs collection for EITHER:
// 1. If an Organization has both NTEE_CD and ACTIVITY
// 2. If an Organization does not have NTEE_CD (which means it only has ACTIVITY)
// 3. If an Organization does not have ACTIVITY (which mean it only has NTEE_CD)
db.bmfs.find({
    \$or: [
        { \$and: [{ NTEE_CD: { \$exists: true }, ACTIVITY: { \$ne: &amp;quot;0&amp;quot; } }] },
        { NTEE_CD: { \$exists: false } },
        { ACTIVITY: { \$eq: &amp;quot;0&amp;quot; } }
    ]
}).forEach((it) =&gt; {
    
    // Determine if this Organization should be included.
    // 1. If it only has NTEE_CD and its NTEE_CD startsWith at least one of the whitelisted NTEEs. It&apos;s good
    // 2. If it only has ACTIVITY and its ACTIVITY_CODES array (the one I made from the previous query)
    //    exists and its ACTIVITY_CODES array includes at least one of the whitelisted Activity Codes.
    // 3. If it has both NTEE_CD and ACTIVITY 
    //    then either its NTEE_CD startsWith at least one the whitelisted NTEEs
    //    or its ACTIVITY_CODES exists and includes at least one of the whitelisted Activity Codes.
    const shouldPush = (it.NTEE_CD &amp;&amp; !it.ACTIVITY &amp;&amp; nteesArr.some(n =&gt; it.NTEE_CD.startsWith(n)))
        || (it.ACTIVITY &amp;&amp; !it.NTEE_CD &amp;&amp; codesArr.some(c =&gt; it.ACTIVITY_CODES &amp;&amp; it.ACTIVITY_CODES.includes(c)))
        || (it.ACTIVITY &amp;&amp; it.NTEE_CD &amp;&amp; (nteesArr.some(n =&gt; it.NTEE_CD.startsWith(n)) || codesArr.some(c =&gt; it.ACTIVITY_CODES &amp;&amp; it.ACTIVITY_CODES.includes(c))));

    // If an Organization should be included, push it to the array.
    if (shouldPush) {
        result.push(it);
    }
});

// After the looping, insert the result array into a new collection 
// (which I intentionally drop at the beginning of this script)
db.queriedbmfs.insert(result);`, `97517900153677200000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Initialize an empty array&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// This is just to be safe, I drop the collection before running this script.&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queriedbmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteMany&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Grab all the Whitelisted Codes&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; codes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;activitycodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Grab all the whitelisted NTEEs&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ntees &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ntees&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Since my whitelisted codes are both MongoDB Collection&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// so they come back with a form of Array of Object with _id and the actual code.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// I only want the Array of codes so I run them both through .map() method to grab the code.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; codesArr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; codes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; nteesArr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ntees&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;code&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Filter the bmfs collection for EITHER:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 1. If an Organization has both NTEE_CD and ACTIVITY&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 2. If an Organization does not have NTEE_CD (which means it only has ACTIVITY)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 3. If an Organization does not have ACTIVITY (which mean it only has NTEE_CD)&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    $or&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $and&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $exists&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $ne&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $exists&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $eq&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Determine if this Organization should be included.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 1. If it only has NTEE_CD and its NTEE_CD startsWith at least one of the whitelisted NTEEs. It&apos;s good&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 2. If it only has ACTIVITY and its ACTIVITY_CODES array (the one I made from the previous query)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//    exists and its ACTIVITY_CODES array includes at least one of the whitelisted Activity Codes.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 3. If it has both NTEE_CD and ACTIVITY &lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//    then either its NTEE_CD startsWith at least one the whitelisted NTEEs&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;//    or its ACTIVITY_CODES exists and includes at least one of the whitelisted Activity Codes.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; shouldPush &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; nteesArr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; codesArr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY_CODES&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY_CODES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nteesArr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;NTEE_CD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; codesArr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;some&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY_CODES&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ACTIVITY_CODES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// If an Organization should be included, push it to the array.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shouldPush&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;it&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// After the looping, insert the result array into a new collection &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// (which I intentionally drop at the beginning of this script)&lt;/span&gt;
db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queriedbmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After this query’s ran, I got the dataset down to 2.8K rows and &lt;code class=&quot;language-text&quot;&gt;queriedbmfs&lt;/code&gt; becomes the main collection that our team works with. And this concludes our first day.&lt;/p&gt;
&lt;p&gt;The first task of the second day was to start parsing the XMLs to get the organizations’ &lt;strong&gt;WEBSITE&lt;/strong&gt; and &lt;strong&gt;PHONE_NUM&lt;/strong&gt;. Since I have the &lt;code class=&quot;language-text&quot;&gt;queriedbmfs&lt;/code&gt; with all the URLs I need on my local &lt;strong&gt;MongoDB&lt;/strong&gt;, I took on the task. Meanwhile, my teammates started cramping up on &lt;strong&gt;AWS Comprehend&lt;/strong&gt;. Back to my XML Parsing task, I needed a parser package which I went with &lt;code class=&quot;language-text&quot;&gt;fast-xml-parser&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;he&lt;/code&gt;. I also needed a &lt;em&gt;HTTP Client&lt;/em&gt; which I went with good ol’ &lt;code class=&quot;language-text&quot;&gt;node-fetch&lt;/code&gt;.  &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Just FYI, all the previous code snippets were Mongo Shell scripts. You can write some JavaScript within the Mongo Shell but because it’s Mongo Shell so variable like &lt;code class=&quot;language-text&quot;&gt;db&lt;/code&gt; works. The below script is written in JS, specifically with NodeJS Runtime, so we need to approach &lt;strong&gt;MongoDB&lt;/strong&gt; a little differently.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;66193041801097126000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Just bringing in the 3rd party libraries
const fetch = require(&apos;node-fetch&apos;);
const mongo = require(&apos;mongodb&apos;);
const parser = require(&apos;fast-xml-parser&apos;);
const he = require(&apos;he&apos;);

// Initialize MongoDB client at localhost:27017, default port of MongoDB
const client = new mongo.MongoClient(&amp;quot;mongodb://localhost:27017&amp;quot;, {
  // some recommended options to work with newer version of MongoDB
  useNewUrlParser: true,
  useUnifiedTopology: true
});

// XML parser options. I don&apos;t have a lot of experience
// working with XML so I don&apos;t really know what the options entail.
// This is from fast-xml-parser documentations
const options = {
  attributeNamePrefix: &apos;@_&apos;,
  attrNodeName: &apos;attr&apos;, //default is &apos;false&apos;
  textNodeName: &apos;#text&apos;,
  ignoreAttributes: true,
  ignoreNameSpace: false,
  allowBooleanAttributes: false,
  parseNodeValue: true,
  parseAttributeValue: false,
  trimValues: true,
  cdataTagName: &apos;__cdata&apos;, //default is &apos;false&apos;
  cdataPositionChar: &apos;\\c&apos;,
  localeRange: &apos;&apos;, //To support non english character in tag/attribute values.
  parseTrueNumberOnly: false,
  attrValueProcessor: a =&gt; he.decode(a, { isAttributeValue: true }), //default is a=&gt;a
  tagValueProcessor: a =&gt; he.decode(a) //default is a=&gt;a
}

// Connect to MongoClient
// Note: I won&apos;t get into Async/Await or Promises in JS
client.connect(async err =&gt; {
  if (err) {
    // if the connection has error
    console.log(&apos;Error connecting: &apos;, err);
    return; // stop executing
  }
  
  // initialize db instance
  const db = client.db(&apos;stl-health-hack&apos;); // connect to stl-health-hack Database
  const xmls = db.collection(&apos;xmls&apos;); // connect (create if not existed, and connect) to xmls collection
  
  const queriedBmfsCursor = db.collection(&apos;queriedbmfs&apos;).find({URL: {\$exists: true}});
  const bmfs = await queriedBmfsCursor.toArray();
  
  // grab all XML URls from BMFs, and construct a GET request for the XML
  // as a form of a Promise (Asynchronous Operation)
  const xmlUrls = bmfs.map(bmf =&gt; fetch(bmf.URL).then(res =&gt; res.text()));
  
  // xmlUrls is an Array of Promises.
  // I intentionally did so so I could utilize Promise.all
  // to execute all the XMLs requests in parallel
  const xmlsResponses = await Promise.all(xmlUrls);
  
  // Loop through the responses
  // parse them into JSON
  // save JSON into the xmls collection
  xmlsResponses.forEach(xml =&gt; {
    if (parser.validate(xml) === true) {
      xmls.insertOne(parser.parse(xml, options));
    }
  })
})`, `66193041801097126000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Just bringing in the 3rd party libraries&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fetch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;node-fetch&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; mongo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;mongodb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; parser &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fast-xml-parser&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; he &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;he&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Initialize MongoDB client at localhost:27017, default port of MongoDB&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;mongo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MongoClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;mongodb://localhost:27017&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// some recommended options to work with newer version of MongoDB&lt;/span&gt;
  useNewUrlParser&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useUnifiedTopology&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// XML parser options. I don&apos;t have a lot of experience&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// working with XML so I don&apos;t really know what the options entail.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// This is from fast-xml-parser documentations&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  attributeNamePrefix&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@_&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  attrNodeName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;attr&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//default is &apos;false&apos;&lt;/span&gt;
  textNodeName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#text&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  ignoreAttributes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  ignoreNameSpace&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  allowBooleanAttributes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  parseNodeValue&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  parseAttributeValue&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  trimValues&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  cdataTagName&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;__cdata&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//default is &apos;false&apos;&lt;/span&gt;
  cdataPositionChar&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;\\c&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  localeRange&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//To support non english character in tag/attribute values.&lt;/span&gt;
  parseTrueNumberOnly&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;attrValueProcessor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; he&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; isAttributeValue&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//default is a=&gt;a&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;tagValueProcessor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; he&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//default is a=&gt;a&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Connect to MongoClient&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Note: I won&apos;t get into Async/Await or Promises in JS&lt;/span&gt;
client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// if the connection has error&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;Error connecting: &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// stop executing&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;// initialize db instance&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; db &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;stl-health-hack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// connect to stl-health-hack Database&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xmls &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;xmls&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// connect (create if not existed, and connect) to xmls collection&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; queriedBmfsCursor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queriedbmfs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$exists&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; bmfs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; queriedBmfsCursor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;// grab all XML URls from BMFs, and construct a GET request for the XML&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// as a form of a Promise (Asynchronous Operation)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xmlUrls &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;bmf&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bmf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;res&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;// xmlUrls is an Array of Promises.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// I intentionally did so so I could utilize Promise.all&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// to execute all the XMLs requests in parallel&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xmlsResponses &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xmlUrls&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  
  &lt;span class=&quot;token comment&quot;&gt;// Loop through the responses&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// parse them into JSON&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// save JSON into the xmls collection&lt;/span&gt;
  xmlsResponses&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;xml&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xml&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      xmls&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;insertOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xml&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So I only grabbed all the XMLs and pushed them into the database. There’s no actual XML Parsing happening yet which it will in the next query. Now that I have the XML content in the database, I can start running queries on it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Back to Mongo Shell&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;36754178438576800000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Get all XMLs
const xmls = db.xmls.find({}).toArray();

db.queriedbmfs.find({}).forEach((it)=&gt; {
    // Match EINs
    const found = xmls.find(xml =&gt; xml.Return.ReturnHeader.Filer.EIN === it.EIN);
    
    // Initialize update object
    const update = {\$set: {}};
    
    if (found) {
        // if has PhoneNum, set PHONE_NUM on the update object
        if (found.Return.ReturnHeader.Filer.PhoneNum) {
            update.\$set[&amp;quot;PHONE_NUM&amp;quot;] = found.Return.ReturnHeader.Filer.PhoneNum;
        }
        
        // if has IRS990EZ
        if (found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;]) {
          
            // if has Website, add WEBSITE to update object
            if (found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;][&amp;quot;WebsiteAddressTxt&amp;quot;]) {
                update.\$set[&amp;quot;WEBSITE&amp;quot;] = found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;][&amp;quot;WebsiteAddressTxt&amp;quot;];
            }
            
            // if has MissionDesc, add MISSION_DESC to update object
            if (found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;][&amp;quot;MissionDesc&amp;quot;]) {
                update.\$set[&amp;quot;MISSION_DESC&amp;quot;] = found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;][&amp;quot;MissionDesc&amp;quot;];
            }
            
            // if has Desc, add XML_DESC to update object
            if (found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;][&amp;quot;Desc&amp;quot;]) {
                update.\$set[&amp;quot;XML_DESC&amp;quot;] = found.Return.ReturnData[&amp;quot;IRS990EZ&amp;quot;][&amp;quot;Desc&amp;quot;];
            }
        } else if (found.Return.ReturnData[&amp;quot;IRS990&amp;quot;]) {
            // same process as above
            if (found.Return.ReturnData[&amp;quot;IRS990&amp;quot;][&amp;quot;WebsiteAddressTxt&amp;quot;]) {
                update.\$set[&amp;quot;WEBSITE&amp;quot;] = found.Return.ReturnData[&amp;quot;IRS990&amp;quot;][&amp;quot;WebsiteAddressTxt&amp;quot;];
            }
            
            if (found.Return.ReturnData[&amp;quot;IRS990&amp;quot;][&amp;quot;MissionDesc&amp;quot;]) {
                update.\$set[&amp;quot;MISSION_DESC&amp;quot;] = found.Return.ReturnData[&amp;quot;IRS990&amp;quot;][&amp;quot;MissionDesc&amp;quot;];
            }
            
            if (found.Return.ReturnData[&amp;quot;IRS990&amp;quot;][&amp;quot;Desc&amp;quot;]) {
                update.\$set[&amp;quot;XML_DESC&amp;quot;] = found.Return.ReturnData[&amp;quot;IRS990&amp;quot;][&amp;quot;Desc&amp;quot;];
            }
        }
        
        // if update object is not an empty object, then update
        if (Object.keys(update.\$set).length) {
            db.queriedbmfs.updateOne({_id: it._id},update)    
        }
    }
});`, `36754178438576800000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Get all XMLs&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xmls &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xmls&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queriedbmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Match EINs&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; found &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; xmls&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;xml&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; xml&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnHeader&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;EIN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Initialize update object&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; update &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// if has PhoneNum, set PHONE_NUM on the update object&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnHeader&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PhoneNum&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;PHONE_NUM&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnHeader&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PhoneNum&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;token comment&quot;&gt;// if has IRS990EZ&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          
            &lt;span class=&quot;token comment&quot;&gt;// if has Website, add WEBSITE to update object&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WebsiteAddressTxt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WEBSITE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WebsiteAddressTxt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;// if has MissionDesc, add MISSION_DESC to update object&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MissionDesc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MISSION_DESC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MissionDesc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token comment&quot;&gt;// if has Desc, add XML_DESC to update object&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Desc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;XML_DESC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990EZ&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Desc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// same process as above&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WebsiteAddressTxt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WEBSITE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;WebsiteAddressTxt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MissionDesc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MISSION_DESC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;MissionDesc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Desc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;XML_DESC&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; found&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Return&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReturnData&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;IRS990&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Desc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        
        &lt;span class=&quot;token comment&quot;&gt;// if update object is not an empty object, then update&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;update&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;$&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            db&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queriedbmfs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateOne&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; it&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;update&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;    
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;The reason why I constructed an &lt;code class=&quot;language-text&quot;&gt;update&lt;/code&gt; object was because one of the requirements was do not include the field if it does not have data/value.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At this point, my &lt;code class=&quot;language-text&quot;&gt;queriedbmfs&lt;/code&gt; collection should have quite a bit more data with &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt; from the XMLs. But little did we know that the data from the XMLs (IRS) was missing a bunch of data and also contains inconsistent data. For example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt; field has inconsistent values for “No Website”:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No &lt;strong&gt;WEBSITE&lt;/strong&gt; field&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WEBSITE&lt;/strong&gt; has value of &lt;code class=&quot;language-text&quot;&gt;&amp;quot;N/A&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WEBSITE&lt;/strong&gt; has value of &lt;code class=&quot;language-text&quot;&gt;&amp;quot;NONE&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WEBSITE&lt;/strong&gt; has value of &lt;code class=&quot;language-text&quot;&gt;&amp;quot;None&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A lot of organizations do not provide &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;So we’re missing quite a few &lt;code class=&quot;language-text&quot;&gt;PHONE_NUM&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;WEBSITE&lt;/code&gt; information which are crucial in terms of Accessibility. After this query-run, it’s starting to get heavily into more &lt;code class=&quot;language-text&quot;&gt;JavaScript&lt;/code&gt; with web scrapping and stuffs. My teammates were also ready to start playing with &lt;strong&gt;AWS Comprehend&lt;/strong&gt;. All of this will have to wait to &lt;strong&gt;Part 2&lt;/strong&gt; of the blog because this one is getting quite lengthy. Thank you for getting this far and hopefully you will continue to follow me through this journey in &lt;strong&gt;&lt;a href=&quot;/blogs/slalom-health-equity-hackathon-2&quot;&gt;Part 2&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How I Get Started]]></title><description><![CDATA[2019 marks my 2 years of working professionally as a Software Developer. Everyday, I enjoy what I do (that’s a lie 😜). Of course, there are…]]></description><link>https://nartc.netlify.com/blogs/how-i-get-started/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/how-i-get-started/</guid><pubDate>Mon, 02 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2019 marks my 2 years of working professionally as a Software Developer. Everyday, I enjoy what I do (&lt;em&gt;that’s a lie&lt;/em&gt; 😜). Of course, there are frustrations with the job: difficult clients, hard-to-solve programming problems, or indecisive management.&lt;/p&gt;
&lt;p&gt;Programming was not my first &lt;strong&gt;career choice&lt;/strong&gt; but it was my first &lt;strong&gt;career&lt;/strong&gt; and programming has also become a huge part of my life. In today’s blog, I want to share with you all about:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;#before-programming&quot;&gt;Before programming?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#when-programming&quot;&gt;When programming?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-programming&quot;&gt;How programming?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-programming&quot;&gt;Why programming?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-present&quot;&gt;The Present&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;before-programming&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#before-programming&quot; aria-label=&quot;before programming permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Before Programming&lt;/h2&gt;
&lt;p&gt;In 2010, I moved to the USA at the age of 19 and literally started over 🙀. I went to college for &lt;strong&gt;Computer Science (&lt;abbr title=&quot;Computer Science&quot;&gt;CS&lt;/abbr&gt;)&lt;/strong&gt; at first without knowing what &lt;strong&gt;&lt;abbr title=&quot;Computer Science&quot;&gt;CS&lt;/abbr&gt;&lt;/strong&gt; really was. I was just going with it because there’s the word “computer” in it. However in 2012, I decided to drop &lt;strong&gt;&lt;abbr title=&quot;Computer Science&quot;&gt;CS&lt;/abbr&gt;&lt;/strong&gt; because I couldn’t understand a single word in &lt;em&gt;Engineering Physics&lt;/em&gt; class. Had I tried better with my English, I might have had a chance to stay with &lt;strong&gt;&lt;abbr title=&quot;Computer Science&quot;&gt;CS&lt;/abbr&gt;&lt;/strong&gt;. After dropping &lt;em&gt;physics&lt;/em&gt; class, I switched to &lt;strong&gt;Information Systems (&lt;abbr title=&quot;Information Systems&quot;&gt;IS&lt;/abbr&gt;)&lt;/strong&gt; major and started preparing to transfer to a 4-year institution. 🏫&lt;/p&gt;
&lt;p&gt;After the transfer, I started working at this warehouse which deals with Medical Supplies. The &lt;em&gt;young&lt;/em&gt; me realized then I liked the way products are organized and distributed. Basically, I was almost &lt;em&gt;tricking&lt;/em&gt; myself into thinking I liked Operational stuffs. Then, I decided to lean towards Business side of &lt;strong&gt;&lt;abbr title=&quot;Information Systems&quot;&gt;IS&lt;/abbr&gt;&lt;/strong&gt; instead of Technical side. How wrong I was!! Last semester came, I had to pass this Capstone class where students have to get in teams, go out to look for our own clients, and solve their business pains using Technology. I was like “I am a Documentations guy” but then I slowly took a role of a Programmer because our team lacked technical people. I wasn’t really sure about my skill at all but little did I know, that decision literally changed my career path. That’s truly when I started &lt;strong&gt;Programming&lt;/strong&gt;. 💻&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Disclaimer: I did take programming courses in the previous semesters but I really didn’t pay attention because I truly thought I was going to be a &lt;em&gt;business man&lt;/em&gt;. 📈📉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;when-programming&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#when-programming&quot; aria-label=&quot;when programming permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;When Programming&lt;/h2&gt;
&lt;p&gt;For this Capstone class project, our team picked the &lt;strong&gt;MEAN Stack&lt;/strong&gt;. For those of you who have no clues, &lt;strong&gt;MEAN&lt;/strong&gt; stands for:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MongoDB&lt;/strong&gt;: The most popular NoSQL database&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ExpressJS&lt;/strong&gt;: The most popular NodeJS framework used to build Web Server&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Angular (Angular 2+)&lt;/strong&gt;: One of the most popular JS Frontend frameworks developed by Google&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NodeJS&lt;/strong&gt;: JavaScript Runtime that enables running JavaScript outside of the Browser (eg: on the server)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sounds super cool to me, to be honest. Well, I didn’t really know anything about any of these 4 technologies. Eventually, I was tasked with working on the &lt;code class=&quot;language-text&quot;&gt;HTML&lt;/code&gt; portion of the &lt;code class=&quot;language-text&quot;&gt;Angular&lt;/code&gt; side then I closely learned &lt;code class=&quot;language-text&quot;&gt;Angular&lt;/code&gt; (&lt;em&gt;Yeah, I know. Scary, right?! &lt;code class=&quot;language-text&quot;&gt;Angular&lt;/code&gt; before &lt;code class=&quot;language-text&quot;&gt;JavaScript&lt;/code&gt;&lt;/em&gt; 😲). Long story short, the following list was my “achievements”:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Spent 150+ hours in the lab learning the &lt;strong&gt;MEAN&lt;/strong&gt; stack with my friend&lt;/li&gt;
&lt;li&gt;Quit my warehouse job about a week after midterm. My friend was like “WT…?!”&lt;/li&gt;
&lt;li&gt;Got the project finished and graduated with a Bachelor Degree in &lt;strong&gt;&lt;abbr title=&quot;Information Systems&quot;&gt;IS&lt;/abbr&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;And most importantly, I realized my passion - &lt;strong&gt;Programming&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I thought it was super cool and super rewarding when something that didn’t exist came to life through our hard work + technologies and that something actually helped a business grow. Next thing I know, I was determined to teach myself how to be a better programmer. Here’s how.&lt;/p&gt;
&lt;h2 id=&quot;how-programming&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#how-programming&quot; aria-label=&quot;how programming permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;How Programming&lt;/h2&gt;
&lt;p&gt;After graduation, I was … &lt;strong&gt;jobless&lt;/strong&gt; and &lt;strong&gt;broke&lt;/strong&gt;. Honestly, I could have just gone back to my old warehouse job and applied for a higher position in the company but &lt;strong&gt;I WANTED TO CODE&lt;/strong&gt;. In addition, it was extremely frustrated at the time because my wife just came to live with me, a &lt;strong&gt;broke&lt;/strong&gt; husband ☹️. On positive note, my wife was very understanding and she was the one who pushed me towards my passion. For 3 months straight after graduation, I coded for 14-16 hours a day for 3 months. My Udemy account was growing like crazy (&lt;em&gt;I know I know, I was tricked by those 9.99 too 😅&lt;/em&gt;). Below was a shorten list of the courses I took:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.udemy.com/angular-4-front-to-back/learn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular 4 Front To Back&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.udemy.com/the-complete-angular-master-class/learn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;The Complete Angular Master Class&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.udemy.com/angular-full-app-with-angular-material-angularfire-ngrx/learn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular Full App With Angular Material Angularfire Ngrx&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.udemy.com/nodejs-express-mongodb-dev-to-deployment/learn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Nodejs Express Mongodb Dev To Deployment&lt;/a&gt;  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;…and a couple more from different sites. During the 3 months of practicing, I also started rebuilding my Capstone’s project (&lt;em&gt;Again, I know, no creativity&lt;/em&gt; 😅). But, the good thing was I wrote much better code in this rebuild over what we did in the Capstone class and the time it took was much shorter as well. I’m talking about 2 weeks versus 4 months 🤯.&lt;/p&gt;
&lt;p&gt;Next, I started applying for Developer jobs. And it was hard. I had no previous experience, no internship under my belt, and had not gone over any official &lt;strong&gt;&lt;abbr title=&quot;Computer Science&quot;&gt;CS&lt;/abbr&gt;&lt;/strong&gt; courses. I applied for tons of positions, maybe got one call or two back. Long story short, I was still &lt;strong&gt;jobless&lt;/strong&gt; and &lt;strong&gt;broke&lt;/strong&gt; 3 months after graduation. My wife was frustrated, I was desperate. Then, I contacted my friend from the old team in the Capstone class and learned that he was working for a Dev Shop (&lt;em&gt;basically, a consultant company but we like to call it Dev Shop&lt;/em&gt;). That friend introduced me to his boss, Kevin, which is my current boss and I did land an interview with them. I was nervous and happy at the same time thinking: “I cannot screw this up”. Show up for the interview, my interviewer, Chris, made the interview super casual. We talked about how I learned, what I already knew and I got to show my &lt;strong&gt;Capstone-project-rebuild&lt;/strong&gt; and talked about how I did it, what I could have done better. Long story short, somehow they gave me a shot for a Contractor position. That’s OK. I will do my best - I said. To me, I was, and still am, extremely truly grateful towards my bosses and my friend who literally trusted and gave me an opportunity in a life time. On 11th Oct 2017, I started my first job as a Developer. That’s how I &lt;strong&gt;programming&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&quot;why-programming&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#why-programming&quot; aria-label=&quot;why programming permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Why Programming&lt;/h2&gt;
&lt;p&gt;As I mentioned earlier, I found it’s rewarding to be creating impacting products that will either realize one’s dream or make the dream better. It also makes my passion becomes a reality. I just love programming, man. For the past year, I’ve learned so much from people around me and I’ve also made many friends along the way. Programming have been opening so many different doors for me where I feel joy doing what I love. I go to meetups to see, hear, and talk to like-minded people. I join online programming communities to share my experience and knowledge. The whole thing has been rewarding both mentally and financially. It makes my marriage less stressful, my wife less doubtful about her leaving her family, friends, and job in Vietnam to come to me.&lt;/p&gt;
&lt;p&gt;All of these things will always remind me about how I get started and the people that were there in the beginning of my career for which they helped &lt;em&gt;launched&lt;/em&gt;. Because of that, I will still keep learning about programming, and keep sharing what I’ve learned with others. That brings uttermost joy to me whenever I can use my knowledge to help others, to enlighten others, and to inspire others. &lt;/p&gt;
&lt;h2 id=&quot;the-present&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-present&quot; aria-label=&quot;the present permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The Present&lt;/h2&gt;
&lt;p&gt;Currently, I am still a &lt;strong&gt;Software Developer&lt;/strong&gt; at &lt;strong&gt;&lt;a href=&quot;http://architectnow.net&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;ArchitectNow&lt;/a&gt;&lt;/strong&gt;. However, I give myself a title of: &lt;strong&gt;TypeScript Enthusiast&lt;/strong&gt;. I love &lt;strong&gt;TypeScript&lt;/strong&gt; and have done so many things with it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I continue to get better at &lt;strong&gt;&lt;a href=&quot;https://angular.io&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular&lt;/a&gt;&lt;/strong&gt; which uses &lt;strong&gt;TypeScript&lt;/strong&gt; as its main programming language&lt;/li&gt;
&lt;li&gt;I discovered &lt;strong&gt;&lt;a href=&quot;https://nestjs.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;NestJS&lt;/a&gt;&lt;/strong&gt;, a progressive &lt;strong&gt;NodeJS&lt;/strong&gt; framework, which uses &lt;strong&gt;TypeScript&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;I get to learn &lt;strong&gt;&lt;a href=&quot;https://reactjs.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;ReactJS&lt;/a&gt;&lt;/strong&gt; and apply &lt;strong&gt;TypeScript&lt;/strong&gt; with it. And it is &lt;strong&gt;AWESOME&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;I created a library called &lt;strong&gt;&lt;a href=&quot;https://github.com/nartc/automapper-nartc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;automapper-nartc&lt;/a&gt;&lt;/strong&gt; to learn even more about &lt;strong&gt;TypeScript&lt;/strong&gt;. (&lt;em&gt;the library is actually working, just FYI&lt;/em&gt; 😛)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;I created a &lt;strong&gt;NestJS&lt;/strong&gt; tutorial series on Youtube&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Repository: &lt;a href=&quot;https://github.com/nartc/nest-mean&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;nest-mean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Youtube: &lt;a href=&quot;https://www.youtube.com/watch?v=Tj_MMY15g6w&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;MEAN Stack with NestJS Part 1&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I just built my blog with &lt;strong&gt;React&lt;/strong&gt;, &lt;strong&gt;Gatsby&lt;/strong&gt; and &lt;strong&gt;TypeScript&lt;/strong&gt;. You can check out how I built this blog &lt;a href=&quot;https://nartc.netlify.com/blogs/how-i-build-this-blog/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;here&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;…and more. If you catch me on social media, I’ll tell more.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I can’t believe that it has been almost 2 years since I started on this path and I do not regret any of it. I have many plans in the near future that I will keep updated through this blog. So stay tuned. Check out my socials if you want to reach out. Thanks for reading and I will see you around.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How I Build This Blog]]></title><description><![CDATA[It’s been a while since I first init a “personal blog” project but I haven’t found the time to actually complete one until now. When I first…]]></description><link>https://nartc.netlify.com/blogs/how-i-build-this-blog/</link><guid isPermaLink="false">https://nartc.netlify.com/blogs/how-i-build-this-blog/</guid><pubDate>Sun, 01 Sep 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It’s been a while since I first &lt;em&gt;init&lt;/em&gt; a “personal blog” project but I haven’t found the time to actually complete one until now. When I first started with the project, I went with &lt;a href=&quot;https://angular.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular&lt;/a&gt; and &lt;a href=&quot;https://angular.io/guide/universal&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Angular Universal&lt;/a&gt;. At the time, I was working on a &lt;a href=&quot;https://reactjs.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;React&lt;/a&gt; project at work so I couldn’t switch context between &lt;strong&gt;Angular&lt;/strong&gt; and &lt;strong&gt;React&lt;/strong&gt; to finish the blog. Then, I discovered &lt;a href=&quot;https://www.gatsbyjs.org&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;GatsbyJS&lt;/a&gt; and it changed my mind on how I wanted to build my blog. After a long time (&lt;em&gt;since Gatsby v1&lt;/em&gt;), I finally put this blog together and here’s how I did it with: &lt;strong&gt;Gatsby&lt;/strong&gt;, &lt;strong&gt;React&lt;/strong&gt; and &lt;strong&gt;TypeScript&lt;/strong&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Of course, I haven’t included many other functionality like &lt;strong&gt;Newsletter&lt;/strong&gt; and such. Those are going to be included and will have their own written blog as well. Stay tuned!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;react--typescript&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#react--typescript&quot; aria-label=&quot;react  typescript permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;React + TypeScript&lt;/h2&gt;
&lt;p&gt;Since this blog is &lt;strong&gt;powered&lt;/strong&gt; by &lt;strong&gt;Gatsby&lt;/strong&gt; so I will save &lt;strong&gt;Gatsby&lt;/strong&gt; for last. For &lt;strong&gt;React&lt;/strong&gt;, I learned (&lt;em&gt;still learning&lt;/em&gt;) &lt;strong&gt;React&lt;/strong&gt; the same way as everybody does, mostly.&lt;/p&gt;
&lt;p&gt;&lt;span
      class=&quot;gatsby-resp-image-wrapper&quot;
      style=&quot;position: relative; display: block; margin-left: auto; margin-right: auto;  max-width: 640px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/7f0b0efb2b5a0464d45474da80cfae05/87339/typescript-in-react.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 55.625%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsSAAALEgHS3X78AAACZklEQVQoz3WS7UtTYRjG/UuqD1mGWrJZOs9e9UzP5nHzuOPc3MHVdDrbsEmUqNFyIzR8qYzAJoyVhC+whVAEYh8KITIy6GMQfQj2X3TdPefZNJH6cHPDc+7nd67rfq6q5sAMjPIompx+WJxemNt9rHp4t7De1KbA0tELJRSrfGPnUm+l/Lysrr5yuQOounQ1R3XBeartGofg0mAWvQyswNTmRaNFghZPYXVrF+/2v9NE5glMogJrBXQSxoH1yj2q0XKoiWxQw0gB571TaGj1Q1I0TM+toLjzGZtv9+nBsyIl7jxil/1ccRl2CCzDbO4gqlocMgzSCJ3ry6J69APODKyRIZDG0moBL7b3aD5bpKf5V7i/vEaxiQXYGEC3e6TsmDoOFJi9FruEJrtMF7sm6XT/JprjBRqeWGSKlhGfWsLj7DqWctv6GeydoX9a1WFloNgNwdkDge1OsDlhdPSROZihQDyNyM05ml7I0+zGVzSqk+RUh5ldFeYTwEOYrbO/AuRQBWY2bHK44WL7C1xPUyQ5A8+tl3A//IXa2BsKp4sYS63wWR1kl0Mccgj7C2QDHNiuK1UgdocxMJahazdmYOqdogvhLTo18hGxfIkOSkRqYhEtbM7U6oHQrvI1/BdoZl3/ozuUJB3qCTKb7FK99y7VRV9jaOUHWVPfyDD4HEPTWaiR2zybdlmDo0srP8oRrBJoveuWRCXMH4CHua0Tl8UgznoXUB3dRU3ygNa//KbCXgmCPAi7S+VqK8DjMF958R36gO8oIhY9a5IPVlHGFVcU1cE8pNQnSuR+knH8PQRtFuHkHP0BLHTFLz+wvHQAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        alt=&quot;React and TypeScript&quot;
        title=&quot;React and TypeScript&quot;
        src=&quot;/static/7f0b0efb2b5a0464d45474da80cfae05/1bed9/typescript-in-react.png&quot;
        srcset=&quot;/static/7f0b0efb2b5a0464d45474da80cfae05/7b64c/typescript-in-react.png 160w,
/static/7f0b0efb2b5a0464d45474da80cfae05/4e610/typescript-in-react.png 320w,
/static/7f0b0efb2b5a0464d45474da80cfae05/1bed9/typescript-in-react.png 640w,
/static/7f0b0efb2b5a0464d45474da80cfae05/7d769/typescript-in-react.png 960w,
/static/7f0b0efb2b5a0464d45474da80cfae05/f3baa/typescript-in-react.png 1280w,
/static/7f0b0efb2b5a0464d45474da80cfae05/87339/typescript-in-react.png 1440w&quot;
        sizes=&quot;(max-width: 640px) 100vw, 640px&quot;
        style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
        loading=&quot;lazy&quot;
      /&gt;
  &lt;/a&gt;
    &lt;/span&gt;
&lt;em&gt;React and TypeScript 😍&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I am an &lt;strong&gt;Angular&lt;/strong&gt; developer. When I was learning &lt;strong&gt;React&lt;/strong&gt;, I was trying to find similarities between the two frameworks. For instance:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Component Declaration&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;38749183626299425000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Angular
@Component({...})
export class SomeComponent {}

// React
export class SomeComponent extends Component&lt;Props, State&gt; {}`, `38749183626299425000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// React&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; State&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Input&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;63380611923552860000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Angular
@Input() someInput: string;

// React
type Props = {
  someInput: string;
}
export class SomeComponent extends Component&lt;Props&gt; {}`, `63380611923552860000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; someInput&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// React&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  someInput&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Props&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Output&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;37338341761719860000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Angular
@Output() event: EventEmitter;

// React
type Props = {
  event: () =&gt; void;
}
export class SomeComponent extends Component&lt;Props&gt; {}`, `37338341761719860000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; event&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; EventEmitter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// React&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SomeComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Props&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Content Projection&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;51666798665892140000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Angular
&lt;ng-content&gt;&lt;/ng-content&gt;

// React
{this.props.children}`, `51666798665892140000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ng&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;content&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ng&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;content&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// React&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;5&quot;&gt;
&lt;li&gt;Fragment&lt;/li&gt;
&lt;/ol&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;15548515282282205000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`// Angular
&lt;ng-container&gt;&lt;/ng-container&gt;

// React
&lt;Fragment&gt;&lt;/Fragment&gt;`, `15548515282282205000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ng&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;container&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ng&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;container&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// React&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Fragment&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Fragment&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Above notes were some of the similarities I was trying to point out when I was learning &lt;strong&gt;React&lt;/strong&gt; as an &lt;strong&gt;Angular&lt;/strong&gt; developer. However, I soon realized that I should have &lt;em&gt;tripped&lt;/em&gt; most of my knowledge about &lt;strong&gt;Angular&lt;/strong&gt; specific to learn &lt;strong&gt;React&lt;/strong&gt; better. I was completely lost and confused when I came to learn some &lt;strong&gt;React&lt;/strong&gt; Advanced Concepts like Render Props and then there’s also &lt;strong&gt;Redux&lt;/strong&gt; 🤯. Reusability differs greatly between the two frameworks as well. Although I am comfortable with &lt;strong&gt;React&lt;/strong&gt; now, I wish I would have spent less time getting familiar with it.&lt;/p&gt;
&lt;p&gt;As for &lt;strong&gt;TypeScript&lt;/strong&gt;, it’s just a natural and personal choice for me. I love &lt;strong&gt;TypeScript&lt;/strong&gt; and writing &lt;strong&gt;React&lt;/strong&gt; with &lt;strong&gt;TypeScript&lt;/strong&gt; feels really nice to me 🥳. I don’t have any personal note about integrating &lt;strong&gt;TypeScript&lt;/strong&gt; with &lt;strong&gt;React&lt;/strong&gt; but to share my &lt;em&gt;ultimate&lt;/em&gt; resources about the two technologies:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/typescript-cheatsheets/react-typescript-cheatsheet&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;React + TypeScript Cheatsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.typescriptlang.org/docs/handbook/advanced-types.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;TypeScript Advanced Types&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;gatsbyjs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#gatsbyjs&quot; aria-label=&quot;gatsbyjs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;GatsbyJS&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Gastby&lt;/strong&gt; is an awesome technology. Though quick to get started, but it’s not quite easy to get used to and start building something for yourself. When I started learning &lt;strong&gt;Gatsby&lt;/strong&gt; months ago, all I did was to pull &lt;a href=&quot;https://www.gatsbyjs.org/starters/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Gatsby Starters&lt;/a&gt; and play with them without the full understanding to actual build something. And I was frustrated 😨.&lt;/p&gt;
&lt;p&gt;Up until about a month ago, I returned to start learning &lt;strong&gt;Gatsby&lt;/strong&gt; from scratch. I followed the &lt;a href=&quot;https://www.gatsbyjs.org/tutorial/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;Gatsby Tutorial&lt;/a&gt; from start to finish. Along the way, I was also trying to integrate &lt;strong&gt;TypeScript&lt;/strong&gt; and &lt;strong&gt;&lt;a href=&quot;https://material-ui.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;MaterialUI&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For my personal blog, I want to go with something minimalistic. I’m not the greatest UX/UI person in the world so I rely on a couple of third parties like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://vincentgarreau.com/particles.js/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;ParticleJS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://material-ui.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;MaterialUI&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For &lt;em&gt;Theme&lt;/em&gt;, I utilize &lt;strong&gt;Context&lt;/strong&gt; in combination with &lt;strong&gt;MaterialUI Theming&lt;/strong&gt; to achieve a simple switch between &lt;em&gt;light 🏙&lt;/em&gt; and &lt;em&gt;dark 🌃&lt;/em&gt; theme. Here’s my &lt;code class=&quot;language-text&quot;&gt;ThemeChangerContext&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;85118934167783980000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`import React, {
  createContext,
  Dispatch,
  FC,
  SetStateAction,
  useCallback,
  useContext,
  useState,
} from &amp;quot;react&amp;quot;;

export type BlogTheme = &amp;quot;light&amp;quot; | &amp;quot;dark&amp;quot;;

export type ThemeChangerContext = {
  theme: BlogTheme;
  setTheme: Dispatch&lt;SetStateAction&lt;BlogTheme&gt;&gt;;
};

const context = createContext&lt;ThemeChangerContext | null&gt;(null);

export const ThemeChangerProvider: FC = ({ children }) =&gt; {
  const [theme, setTheme] = useState&lt;BlogTheme&gt;(&amp;quot;light&amp;quot;);

  return (
    &lt;context.Provider value={{ theme, setTheme: useCallback(setTheme, []) }}&gt;
      {children}
    &lt;/context.Provider&gt;
  );
};

export const useThemeChangerContext = () =&gt; {
  const ctx = useContext(context) as ThemeChangerContext;

  if (ctx === undefined) {
    throw new Error(
      &amp;quot;useThemeChangerContext must be used within ThemeChangerProvider&amp;quot;
    );
  }

  return ctx;
};`, `85118934167783980000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  createContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Dispatch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;FC&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  SetStateAction&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useCallback&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  useState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; BlogTheme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;light&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dark&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; ThemeChangerContext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  theme&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlogTheme&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  setTheme&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Dispatch&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;SetStateAction&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;BlogTheme&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; context &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; createContext&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeChangerContext &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ThemeChangerProvider&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setTheme&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; useState&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;BlogTheme&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;light&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Provider value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setTheme&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;setTheme&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Provider&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;useThemeChangerContext&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ctx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; ThemeChangerContext&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;useThemeChangerContext must be used within ThemeChangerProvider&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And use it on my &lt;code class=&quot;language-text&quot;&gt;Layout&lt;/code&gt;:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;99182608096843780000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`const Layout: FC = ({ children }) =&gt; {
  const { theme } = useThemeChangerContext();
  const muiTheme = useMemo(() =&gt; buildTheme(theme), [theme]);

  return (
    &lt;ThemeProvider theme={muiTheme}&gt;
      &lt;CssBaseline /&gt;
      &lt;ThemeToggler /&gt;
      {children}
    &lt;/ThemeProvider&gt;
  );
};

const LayoutWithThemeChanger: FC = ({ children }) =&gt; {
  return (
    &lt;ThemeChangerProvider&gt;
      &lt;Layout&gt;{children}&lt;/Layout&gt;
    &lt;/ThemeChangerProvider&gt;
  );
};

export default LayoutWithThemeChanger;`, `99182608096843780000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-typescript line-numbers&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Layout&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; theme &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useThemeChangerContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; muiTheme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;buildTheme&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeProvider theme&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;muiTheme&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;CssBaseline &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeToggler &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ThemeProvider&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; LayoutWithThemeChanger&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;FC&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeChangerProvider&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Layout&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Layout&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ThemeChangerProvider&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; LayoutWithThemeChanger&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice how I use &lt;code class=&quot;language-text&quot;&gt;useMemo&lt;/code&gt; to cache so when my &lt;code class=&quot;language-text&quot;&gt;Layout&lt;/code&gt; is rendered and the &lt;code class=&quot;language-text&quot;&gt;theme&lt;/code&gt; hasn’t changed, I don’t have to execute &lt;code class=&quot;language-text&quot;&gt;buildTheme()&lt;/code&gt; again.&lt;/p&gt;
&lt;p&gt;For overall feels and looks, I just utilize &lt;strong&gt;MaterialUI Components&lt;/strong&gt; where I see fit. &lt;a href=&quot;https://material-ui.com/styles/basics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noreferrer&quot;&gt;MaterialUI Styles&lt;/a&gt; is a very important concept that you might want to pick up if you want to use &lt;strong&gt;MaterialUI&lt;/strong&gt; efficiently.&lt;/p&gt;
&lt;p&gt;For the content, I will not go over &lt;strong&gt;Gatsby API&lt;/strong&gt; but I want to highlight a couple points:&lt;/p&gt;
&lt;h4 id=&quot;createpages&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#createpages&quot; aria-label=&quot;createpages permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;createPages&lt;/h4&gt;
&lt;p&gt;I want to have a &lt;strong&gt;Pagination&lt;/strong&gt; on my &lt;strong&gt;Blogs&lt;/strong&gt; page. Here’s what I came up with:&lt;/p&gt;
&lt;div
              class=&quot;gatsby-code-button-container&quot;
              data-toaster-id=&quot;58033520863206280000&quot;
              data-toaster-class=&quot;gatsby-code-button-toaster&quot;
              data-toaster-text-class=&quot;gatsby-code-button-toaster-text&quot;
              data-toaster-text=&quot;Copied to clipboard 📋&quot;
              data-toaster-duration=&quot;3500&quot;
              onClick=&quot;copyToClipboard(`exports.createPages = async ({ graphql, actions }) =&gt; {
  const { createPage } = actions;

  const result = await graphql(\`
    {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              title
              tags
            }
          }
        }
      }
      site {
        siteMetadata {
          blogsPerPage
        }
      }
    }
  \`);

  if (result.errors) {
    console.error(result.errors);
    throw new Error(result.errors);
  }

  // Templates
  const blogsTemplate = path.resolve(&amp;quot;./src/templates/blogs.tsx&amp;quot;);

  const blogs = result.data.allMarkdownRemark.edges;
  const blogsPerPage = result.data.site.siteMetadata.blogsPerPage;
  const numPages = Math.ceil(blogs.length / blogsPerPage);

  Array.from({ length: numPages }).forEach((_, index) =&gt; {
    createPage({
      path: index === 0 ? &amp;quot;/blogs&amp;quot; : \`/blogs/\${index + 1}\`,
      component: blogsTemplate,
      context: {
        limit: blogsPerPage,
        skip: index * blogsPerPage,
        numPages,
        currentPage: index + 1,
        total: blogs.length,
      },
    });
  });
}`, `58033520863206280000`)&quot;
            &gt;
              &lt;div
                class=&quot;gatsby-code-button&quot;
                data-tooltip=&quot;&quot;
              &gt;
                &lt;svg class=&quot;gatsby-code-button-icon&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path fill=&quot;none&quot; d=&quot;M0 0h24v24H0V0z&quot;/&gt;&lt;path d=&quot;M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z&quot;/&gt;&lt;/svg&gt;
              &lt;/div&gt;
            &lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-javascript line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;exports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;createPages&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; graphql&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; actions &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; createPage &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; actions&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;graphql&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
            frontmatter {
              title
              tags
            }
          }
        }
      }
      site {
        siteMetadata {
          blogsPerPage
        }
      }
    }
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Templates&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; blogsTemplate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;./src/templates/blogs.tsx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; blogs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allMarkdownRemark&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;edges&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; blogsPerPage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;site&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;siteMetadata&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blogsPerPage&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; numPages &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;blogs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; blogsPerPage&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; length&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; numPages &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;createPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/blogs&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/blogs/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; blogsTemplate&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      context&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        limit&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; blogsPerPage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        skip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; blogsPerPage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        numPages&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        currentPage&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        total&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; blogs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above will give me each &lt;code class=&quot;language-text&quot;&gt;blogs/{pageNumber}&lt;/code&gt; for every 10 blog post that I have which is pretty sweet.&lt;/p&gt;
&lt;h4 id=&quot;graphql&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#graphql&quot; aria-label=&quot;graphql permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;graphql&lt;/h4&gt;
&lt;p&gt;I am a hard-fan on typings so working with &lt;code class=&quot;language-text&quot;&gt;graphql&lt;/code&gt; in the beginning wasn’t really a pleasant. Luckily, I found &lt;strong&gt;Webstorm GraphQL plugin&lt;/strong&gt; and it literally saved my life (&lt;em&gt;well not really, but it did save my interest in GraphQL&lt;/em&gt;). Setup is easy as well:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;code class=&quot;language-text&quot;&gt;GraphQL&lt;/code&gt; plugin&lt;/li&gt;
&lt;li&gt;Setup a &lt;code class=&quot;language-text&quot;&gt;.graphqlconfig&lt;/code&gt; file like following:&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre style=&quot;counter-reset: linenumber NaN&quot; class=&quot;language-text line-numbers&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;{
  &amp;quot;projects&amp;quot;: {
    &amp;quot;blog&amp;quot;: { // notice of this &amp;quot;blog&amp;quot; name
      &amp;quot;name&amp;quot;: &amp;quot;Untitled GraphQL Schema&amp;quot;,
      &amp;quot;schemaPath&amp;quot;: &amp;quot;schema.graphql&amp;quot;,
      &amp;quot;extensions&amp;quot;: {
        &amp;quot;endpoints&amp;quot;: {
          &amp;quot;Default GraphQL Endpoint&amp;quot;: {
            &amp;quot;url&amp;quot;: &amp;quot;http://localhost:8000/___graphql&amp;quot;,
            &amp;quot;headers&amp;quot;: {
              &amp;quot;user-agent&amp;quot;: &amp;quot;JS GraphQL&amp;quot;
            },
            &amp;quot;introspect&amp;quot;: false
          }
        }
      }
    }
  }
}&lt;/code&gt;&lt;span aria-hidden=&quot;true&quot; class=&quot;line-numbers-rows&quot; style=&quot;white-space: normal; width: auto; left: 0;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;Install &lt;code class=&quot;language-text&quot;&gt;graphql-cli&lt;/code&gt; npm package.&lt;/li&gt;
&lt;li&gt;Setup a script (or not): &lt;code class=&quot;language-text&quot;&gt;graph: graphql get-schema --project blog&lt;/code&gt;. The &lt;code class=&quot;language-text&quot;&gt;--project&lt;/code&gt; points to the project name you set up in the config.&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;npm run graph&lt;/code&gt; against a running &lt;strong&gt;Gatsby&lt;/strong&gt; instance.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;graphql-cli&lt;/code&gt; will output a &lt;code class=&quot;language-text&quot;&gt;schema.graphql&lt;/code&gt; file and this file is all the &lt;code class=&quot;language-text&quot;&gt;GraphQL&lt;/code&gt; plugin needs to provide intellisense in your &lt;code class=&quot;language-text&quot;&gt;GraphQL&lt;/code&gt; queries. Awesome 🥳!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can also generate &lt;strong&gt;TypeScript&lt;/strong&gt; types from &lt;code class=&quot;language-text&quot;&gt;scheme.graphql&lt;/code&gt; but the types aren’t really helpful since they’re all of type &lt;code class=&quot;language-text&quot;&gt;Maybe&amp;lt;T&amp;gt;&lt;/code&gt; and it requires a lot of &lt;code class=&quot;language-text&quot;&gt;null checking&lt;/code&gt; in your code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;end&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#end&quot; aria-label=&quot;end permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;End&lt;/h2&gt;
&lt;p&gt;Rather than the points that I mentioned above, it all comes down to your own &lt;strong&gt;Customization&lt;/strong&gt; and how you want your blog to look, act, and feel like. &lt;strong&gt;Gatsby&lt;/strong&gt; is a great tool that will allow you to build a full SEO-supported personal blog (or even more). Utilizing &lt;strong&gt;React&lt;/strong&gt; allows you to build your components in a more concise and performant way. Overall, putting this blog together was a joy to me and I will definitely keep working on it to include more features in the future. Thanks for reading!&lt;/p&gt;</content:encoded></item></channel></rss>