{"id":29317,"date":"2018-10-24T00:00:00","date_gmt":"2018-10-23T22:00:00","guid":{"rendered":"https:\/\/blexin.com\/componenti-avanzati-in-angular-come-creare-una-dashboard\/"},"modified":"2021-05-20T19:30:53","modified_gmt":"2021-05-20T17:30:53","slug":"angular-advanced-components-how-to-create-a-dashboard","status":"publish","type":"post","link":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/","title":{"rendered":"Angular Advanced Components: how to create a dashboard"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"552\" data-attachment-id=\"29247\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/0b2fdd00-192a-4095-b0bc-627097e78f0e-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&amp;ssl=1\" data-orig-size=\"1024,552\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"0b2fdd00-192a-4095-b0bc-627097e78f0e\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?resize=1024%2C552&#038;ssl=1\" alt=\"\" class=\"wp-image-29247\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e-980x528.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e-480x259.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">In the last few days, I was in Rome by a customer, who is porting a vb6 application to Angular. During the code review, he asks me to add a dashboard with resizable widgets, that can be positioned on the page with the classical drag &amp; drop approach.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">We did some search on google, and we choose to start from gridstack.js (<a href=\"http:\/\/gridstackjs.com\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/gridstackjs.com\/<\/a>) which&nbsp;is a JavaScript library based on jQuery and jQuery-UI drag &amp; drop feature. The employment of&nbsp;jQuery is almost anachronistic today, but it is still very used and some plugins are really interesting. This is then a good opportunity to analyze, at&nbsp;the same time, some advanced features of Angular components and how to integrate jQuery plugins.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As a first step we create a new project with the angular-cli, enter in the project folder, install the gridstack dependency, generate two new components named dashboard and widget, and finally open Visual Studio Code on the folder:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>ng new dashboard<\/li><li>cd dashboard<\/li><li>npm install -save jquery jqueryui lodash gridstack<\/li><li>ng g component dashboard<\/li><li>ng g component widget<\/li><li>code .<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If you prefer you can link jquery, jquery-ui, lodash, and gridstack from a CDN, according to your requirements, but if you have downloaded these libraries you have to add their paths in the&nbsp;<em>angular-cli.json<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"785\" height=\"411\" data-attachment-id=\"29250\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/6d6274b6-9cbb-44f2-ac7c-354cb405c902-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/6d6274b6-9cbb-44f2-ac7c-354cb405c902.png?fit=785%2C411&amp;ssl=1\" data-orig-size=\"785,411\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"6d6274b6-9cbb-44f2-ac7c-354cb405c902\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/6d6274b6-9cbb-44f2-ac7c-354cb405c902.png?fit=785%2C411&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/6d6274b6-9cbb-44f2-ac7c-354cb405c902.png?resize=785%2C411&#038;ssl=1\" alt=\"\" class=\"wp-image-29250\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/6d6274b6-9cbb-44f2-ac7c-354cb405c902.png 785w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/6d6274b6-9cbb-44f2-ac7c-354cb405c902-480x251.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 785px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">According to the documentation, we can create a simple dashboard by creating a container with a \u2018grid-stack\u2019 class, that will contain the widget container identified by \u2018grid-stack-item\u2019 class, and some custom data-* attribute for the position (<em>data-gs-x<\/em>&nbsp;and&nbsp;<em>data-gs-y<\/em>), the width (<em>data-gs-width<\/em>) and the height (<em>data-gs-height<\/em>). Our dashboard.component.html will be as follow:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"980\" height=\"768\" data-attachment-id=\"29252\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/0f1a5701-26c0-4efa-a055-46950d4159d1-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0f1a5701-26c0-4efa-a055-46950d4159d1.png?fit=980%2C768&amp;ssl=1\" data-orig-size=\"980,768\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"0f1a5701-26c0-4efa-a055-46950d4159d1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0f1a5701-26c0-4efa-a055-46950d4159d1.png?fit=980%2C768&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0f1a5701-26c0-4efa-a055-46950d4159d1.png?resize=980%2C768&#038;ssl=1\" alt=\"\" class=\"wp-image-29252\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0f1a5701-26c0-4efa-a055-46950d4159d1.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0f1a5701-26c0-4efa-a055-46950d4159d1-480x376.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 980px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The widget content is identified by the \u2018grid-stack-item-content\u2019 class, that we can use to stylize the aspect of the widget in the dashboard.component.css file:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"358\" height=\"182\" data-attachment-id=\"29255\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/5852e5aa-2581-4a7f-93af-5e7b14a6a00e-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/5852e5aa-2581-4a7f-93af-5e7b14a6a00e.png?fit=358%2C182&amp;ssl=1\" data-orig-size=\"358,182\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"5852e5aa-2581-4a7f-93af-5e7b14a6a00e\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/5852e5aa-2581-4a7f-93af-5e7b14a6a00e.png?fit=358%2C182&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/5852e5aa-2581-4a7f-93af-5e7b14a6a00e.png?resize=358%2C182&#038;ssl=1\" alt=\"\" class=\"wp-image-29255\" srcset=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/5852e5aa-2581-4a7f-93af-5e7b14a6a00e.png?w=358&amp;ssl=1 358w, https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/5852e5aa-2581-4a7f-93af-5e7b14a6a00e.png?resize=300%2C153&amp;ssl=1 300w\" sizes=\"auto, (max-width: 358px) 100vw, 358px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Gridstack<\/strong>&nbsp;is a jQuery plugin, then we need to use jQuery in our code to init the plugin. The problem with jQuery is that you have to do assumption on the HTML structure to select the appropriate element of the DOM, in this case we need to add the following code row:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>$(&#8216;.grid-stack&#8217;).gridstack();<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In Angular, the separation between the component logic (the .ts file) and the HTML structure (the .html file) is very important and, usually, we encapsulate all the calls that need to know the dom in an Angular Directive, especially because we need to have the DOM ready when executing the jQuery call. But, in this case, the component executes only this call, because all the work will be done by the plugin. This one may be the only case where we can do some assumptions on the HTML structure, and dirty the component logic with the jQuery call.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If we don&#8217;t like it, we can use the&nbsp;<strong>@ViewChild<\/strong>&nbsp;decorator on an ElementRef property and add a&nbsp;<em>#gridStackContainer<\/em>&nbsp;on the right div:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"117\" data-attachment-id=\"29258\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/286e19a7-2861-4b19-9e2d-9da9d7d44701-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/286e19a7-2861-4b19-9e2d-9da9d7d44701.png?fit=1024%2C117&amp;ssl=1\" data-orig-size=\"1024,117\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"286e19a7-2861-4b19-9e2d-9da9d7d44701\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/286e19a7-2861-4b19-9e2d-9da9d7d44701.png?fit=1024%2C117&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/286e19a7-2861-4b19-9e2d-9da9d7d44701.png?resize=1024%2C117&#038;ssl=1\" alt=\"\" class=\"wp-image-29258\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/286e19a7-2861-4b19-9e2d-9da9d7d44701.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/286e19a7-2861-4b19-9e2d-9da9d7d44701-980x112.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/286e19a7-2861-4b19-9e2d-9da9d7d44701-480x55.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">At this point, the question is: when? When is the DOM ready for the jQuery call from the component?. At this purpose, the Angular component has some hooks that are invoked in various phases of the component lifecycle. More information about this topic can be found in the official documentation (<a rel=\"noreferrer noopener\" href=\"https:\/\/angular.io\/guide\/lifecycle-hooks\" target=\"_blank\">https:\/\/angular.io\/guide\/lifecycle-hooks<\/a>). In our case, we need the AfterViewInit hook, that is called after Angular initialize the component view (and also his potential child views):<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"768\" data-attachment-id=\"29261\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/4d562304-3375-4bf9-bfbe-8465a83878eb-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb.png?fit=627%2C768&amp;ssl=1\" data-orig-size=\"627,768\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"4d562304-3375-4bf9-bfbe-8465a83878eb\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb.png?fit=627%2C768&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb.png?resize=627%2C768&#038;ssl=1\" alt=\"\" class=\"wp-image-29261\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb.png 627w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb-480x588.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 627px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Obviously, Typescript doesn\u2019t know the jQuery $ symbol, then we have to declare a const to pass the Typescript transpilation, as you can see after the import statement:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>declare const $: any;<\/em><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To end this first step, we have to change the app.component.html as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"398\" height=\"35\" data-attachment-id=\"29263\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/94d63fe8-f4d5-43e5-8493-4d0059885917-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/94d63fe8-f4d5-43e5-8493-4d0059885917.png?fit=398%2C35&amp;ssl=1\" data-orig-size=\"398,35\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"94d63fe8-f4d5-43e5-8493-4d0059885917\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/94d63fe8-f4d5-43e5-8493-4d0059885917.png?fit=398%2C35&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/94d63fe8-f4d5-43e5-8493-4d0059885917.png?resize=398%2C35&#038;ssl=1\" alt=\"\" class=\"wp-image-29263\" srcset=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/94d63fe8-f4d5-43e5-8493-4d0059885917.png?w=398&amp;ssl=1 398w, https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/94d63fe8-f4d5-43e5-8493-4d0059885917.png?resize=300%2C26&amp;ssl=1 300w\" sizes=\"auto, (max-width: 398px) 100vw, 398px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Running our application with the&nbsp;<em>ng serve -o command<\/em>, we can see the result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"613\" data-attachment-id=\"29266\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/339c0057-256c-43d8-8d01-5a298bd294f2-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/339c0057-256c-43d8-8d01-5a298bd294f2.png?fit=1024%2C613&amp;ssl=1\" data-orig-size=\"1024,613\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"339c0057-256c-43d8-8d01-5a298bd294f2\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/339c0057-256c-43d8-8d01-5a298bd294f2.png?fit=1024%2C613&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/339c0057-256c-43d8-8d01-5a298bd294f2.png?resize=1024%2C613&#038;ssl=1\" alt=\"\" class=\"wp-image-29266\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/339c0057-256c-43d8-8d01-5a298bd294f2.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/339c0057-256c-43d8-8d01-5a298bd294f2-980x587.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/339c0057-256c-43d8-8d01-5a298bd294f2-480x287.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Ok, it\u2019s time to abstract our components to make them reusable. We start moving the widget structure in the widget component, exposing the widget properties as component input properties. The&nbsp;<em>widget.component.ts<\/em>&nbsp;will be as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"534\" height=\"667\" data-attachment-id=\"29269\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/ef012482-8e95-42e5-b087-29b9f578eaa8-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ef012482-8e95-42e5-b087-29b9f578eaa8.png?fit=534%2C667&amp;ssl=1\" data-orig-size=\"534,667\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"ef012482-8e95-42e5-b087-29b9f578eaa8\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ef012482-8e95-42e5-b087-29b9f578eaa8.png?fit=534%2C667&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/ef012482-8e95-42e5-b087-29b9f578eaa8.png?resize=534%2C667&#038;ssl=1\" alt=\"\" class=\"wp-image-29269\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ef012482-8e95-42e5-b087-29b9f578eaa8.png 534w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/ef012482-8e95-42e5-b087-29b9f578eaa8-480x600.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 534px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The&nbsp;<em>widget.component.html<\/em>&nbsp;could be as follow:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"515\" height=\"289\" data-attachment-id=\"29272\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/35f797e9-0bd1-4325-b9d0-caf2328d0c3f-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/35f797e9-0bd1-4325-b9d0-caf2328d0c3f.png?fit=515%2C289&amp;ssl=1\" data-orig-size=\"515,289\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"35f797e9-0bd1-4325-b9d0-caf2328d0c3f\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/35f797e9-0bd1-4325-b9d0-caf2328d0c3f.png?fit=515%2C289&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/35f797e9-0bd1-4325-b9d0-caf2328d0c3f.png?resize=515%2C289&#038;ssl=1\" alt=\"\" class=\"wp-image-29272\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/35f797e9-0bd1-4325-b9d0-caf2328d0c3f.png 515w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/35f797e9-0bd1-4325-b9d0-caf2328d0c3f-480x269.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 515px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But as the compiler tells us, we can\u2019t bind unknown attribute to out property, and the data-* are too generic to be known by angular. We can solve the problem using the [attr.] binding:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"281\" data-attachment-id=\"29274\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68.png?fit=512%2C281&amp;ssl=1\" data-orig-size=\"512,281\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68.png?fit=512%2C281&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68.png?resize=512%2C281&#038;ssl=1\" alt=\"\" class=\"wp-image-29274\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68.png 512w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/aa77f0ba-a9d4-4514-95bc-5d3ab0e84d68-480x263.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 512px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Note the ng-content element: it permits us to project the content in our component:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"778\" height=\"91\" data-attachment-id=\"29277\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/35a76158-3a76-4c77-8762-cb5b013370da-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/35a76158-3a76-4c77-8762-cb5b013370da.png?fit=778%2C91&amp;ssl=1\" data-orig-size=\"778,91\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"35a76158-3a76-4c77-8762-cb5b013370da\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/35a76158-3a76-4c77-8762-cb5b013370da.png?fit=778%2C91&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/35a76158-3a76-4c77-8762-cb5b013370da.png?resize=778%2C91&#038;ssl=1\" alt=\"\" class=\"wp-image-29277\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/35a76158-3a76-4c77-8762-cb5b013370da.png 778w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/35a76158-3a76-4c77-8762-cb5b013370da-480x56.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 778px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The span&nbsp;Widget 1&nbsp;element will be then projected in the widget component, exactly at ng-content position. This is a very cool feature and we can use it also in the&nbsp;<em>dashboard.component.html<\/em>:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"90\" data-attachment-id=\"29282\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/9711491b-262c-4ba8-855d-6212b87281a9-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/9711491b-262c-4ba8-855d-6212b87281a9.png?fit=1024%2C90&amp;ssl=1\" data-orig-size=\"1024,90\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"9711491b-262c-4ba8-855d-6212b87281a9\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/9711491b-262c-4ba8-855d-6212b87281a9.png?fit=1024%2C90&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/9711491b-262c-4ba8-855d-6212b87281a9.png?resize=1024%2C90&#038;ssl=1\" alt=\"\" class=\"wp-image-29282\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/9711491b-262c-4ba8-855d-6212b87281a9.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/9711491b-262c-4ba8-855d-6212b87281a9-980x86.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/9711491b-262c-4ba8-855d-6212b87281a9-480x42.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">So, our app.component.html will become as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"578\" height=\"768\" data-attachment-id=\"29285\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/804015ca-741d-4d4f-87eb-27155d440a3a-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/804015ca-741d-4d4f-87eb-27155d440a3a.png?fit=578%2C768&amp;ssl=1\" data-orig-size=\"578,768\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"804015ca-741d-4d4f-87eb-27155d440a3a\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/804015ca-741d-4d4f-87eb-27155d440a3a.png?fit=578%2C768&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/804015ca-741d-4d4f-87eb-27155d440a3a.png?resize=578%2C768&#038;ssl=1\" alt=\"\" class=\"wp-image-29285\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/804015ca-741d-4d4f-87eb-27155d440a3a.png 578w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/804015ca-741d-4d4f-87eb-27155d440a3a-480x638.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 578px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">But, when we run the application, the result is not as we would expect:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"455\" data-attachment-id=\"29287\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba.png?fit=1024%2C455&amp;ssl=1\" data-orig-size=\"1024,455\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"8b96cb20-e9e0-41dc-b6f4-f726320b14ba\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba.png?fit=1024%2C455&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba.png?resize=1024%2C455&#038;ssl=1\" alt=\"\" class=\"wp-image-29287\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba-980x435.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8b96cb20-e9e0-41dc-b6f4-f726320b14ba-480x213.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Why? If we show the actual DOM structure, we can see the problem clearly:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"531\" height=\"410\" data-attachment-id=\"29290\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/89b65386-18f6-4aa8-b1b3-23b28e62d8be-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/89b65386-18f6-4aa8-b1b3-23b28e62d8be.png?fit=531%2C410&amp;ssl=1\" data-orig-size=\"531,410\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"89b65386-18f6-4aa8-b1b3-23b28e62d8be\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/89b65386-18f6-4aa8-b1b3-23b28e62d8be.png?fit=531%2C410&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/89b65386-18f6-4aa8-b1b3-23b28e62d8be.png?resize=531%2C410&#038;ssl=1\" alt=\"\" class=\"wp-image-29290\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/89b65386-18f6-4aa8-b1b3-23b28e62d8be.png 531w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/89b65386-18f6-4aa8-b1b3-23b28e62d8be-480x371.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 531px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Between the dashboard and the widget, Angular places an element with the name of the selector of the component and this create problems with several jQuery plugins, like gridstack, because it searches the direct child with the \u2018grid-stack-item\u2019 class and data-* attributes, but it founds the app-widget element instead of our div element.&nbsp;How can we solve the problem? Our widget cannot be necessarily a div, so we can move the grid-stack-item class and the data-* properties on the element using the&nbsp;<em>host<\/em>&nbsp;component property or, better, the&nbsp;<em>@HostBinding()<\/em>&nbsp;decorator:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"627\" height=\"768\" data-attachment-id=\"29292\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/4d562304-3375-4bf9-bfbe-8465a83878eb-1-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb-1.png?fit=627%2C768&amp;ssl=1\" data-orig-size=\"627,768\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"4d562304-3375-4bf9-bfbe-8465a83878eb-1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb-1.png?fit=627%2C768&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb-1.png?resize=627%2C768&#038;ssl=1\" alt=\"\" class=\"wp-image-29292\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb-1.png 627w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4d562304-3375-4bf9-bfbe-8465a83878eb-1-480x588.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 627px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Thanks to HostBinding decorator we can add the bound element on our component selector, and we will solve our problem:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"454\" data-attachment-id=\"29295\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/8d03f275-331d-4896-b741-f36587a83dd7-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8d03f275-331d-4896-b741-f36587a83dd7.png?fit=1024%2C454&amp;ssl=1\" data-orig-size=\"1024,454\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"8d03f275-331d-4896-b741-f36587a83dd7\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8d03f275-331d-4896-b741-f36587a83dd7.png?fit=1024%2C454&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/8d03f275-331d-4896-b741-f36587a83dd7.png?resize=1024%2C454&#038;ssl=1\" alt=\"\" class=\"wp-image-29295\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8d03f275-331d-4896-b741-f36587a83dd7.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8d03f275-331d-4896-b741-f36587a83dd7-980x434.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/8d03f275-331d-4896-b741-f36587a83dd7-480x213.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Perfect, but what happens if the widgets come&nbsp;from a service? How does our implementation change? It seems a simple question&nbsp;because we have only to simulate a service call and cycling on its results. Ok, try to do this. If we add two files to the dashboard component, a&nbsp;<em>dashboard.model.ts<\/em>&nbsp;to create a type for the Widget response:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"291\" height=\"218\" data-attachment-id=\"29298\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/b26fd97b-022e-4210-937e-94ca981efc2e-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/b26fd97b-022e-4210-937e-94ca981efc2e.png?fit=291%2C218&amp;ssl=1\" data-orig-size=\"291,218\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"b26fd97b-022e-4210-937e-94ca981efc2e\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/b26fd97b-022e-4210-937e-94ca981efc2e.png?fit=291%2C218&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/b26fd97b-022e-4210-937e-94ca981efc2e.png?resize=291%2C218&#038;ssl=1\" alt=\"\" class=\"wp-image-29298\" srcset=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/b26fd97b-022e-4210-937e-94ca981efc2e.png?w=291&amp;ssl=1 291w, https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/b26fd97b-022e-4210-937e-94ca981efc2e.png?resize=200%2C150&amp;ssl=1 200w\" sizes=\"auto, (max-width: 291px) 100vw, 291px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">And a&nbsp;<em>dashboard.service.ts<\/em>&nbsp;to simulate the service call by creating and returning a Subject and by using a setTimeout to delay the data retrieving of one second:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.tolist.net\/Storage\/d6559c44-6647-4f0f-9bca-1cfdc44a4451\/Articles\/6969d711-c586-4fcb-ac40-a515d0216ba6.png?w=1080\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If we inject the service in our dashboard.component.ts, we can call the service and store the result in a specified array as follow:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"761\" height=\"768\" data-attachment-id=\"29300\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/9071f33c-6a2e-4420-9996-52d611f44d98-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/9071f33c-6a2e-4420-9996-52d611f44d98.png?fit=761%2C768&amp;ssl=1\" data-orig-size=\"761,768\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"9071f33c-6a2e-4420-9996-52d611f44d98\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/9071f33c-6a2e-4420-9996-52d611f44d98.png?fit=761%2C768&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/9071f33c-6a2e-4420-9996-52d611f44d98.png?resize=761%2C768&#038;ssl=1\" alt=\"\" class=\"wp-image-29300\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/9071f33c-6a2e-4420-9996-52d611f44d98.png 761w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/9071f33c-6a2e-4420-9996-52d611f44d98-480x484.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 761px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The dashboard.component.html changes, according to the new source of the widgets, as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"158\" data-attachment-id=\"29303\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1.png?fit=1024%2C158&amp;ssl=1\" data-orig-size=\"1024,158\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"1e37b847-c085-4ac0-ac7a-f00913deb70b-1\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1.png?fit=1024%2C158&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1.png?resize=1024%2C158&#038;ssl=1\" alt=\"\" class=\"wp-image-29303\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1-980x151.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/1e37b847-c085-4ac0-ac7a-f00913deb70b-1-480x74.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">When we run the application, however, we realize that something doesn\u2019t work and the console doesn\u2019t show errors.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"551\" data-attachment-id=\"29306\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/0b98ce37-3b36-46ed-9147-a1bb04d05c92-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b98ce37-3b36-46ed-9147-a1bb04d05c92.png?fit=1024%2C551&amp;ssl=1\" data-orig-size=\"1024,551\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"0b98ce37-3b36-46ed-9147-a1bb04d05c92\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b98ce37-3b36-46ed-9147-a1bb04d05c92.png?fit=1024%2C551&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b98ce37-3b36-46ed-9147-a1bb04d05c92.png?resize=1024%2C551&#038;ssl=1\" alt=\"\" class=\"wp-image-29306\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0b98ce37-3b36-46ed-9147-a1bb04d05c92.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0b98ce37-3b36-46ed-9147-a1bb04d05c92-980x527.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/0b98ce37-3b36-46ed-9147-a1bb04d05c92-480x258.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The problem is that when we call&nbsp;<em>$(this.gridStackContainer.nativeElement).gridstack();<\/em>&nbsp;the dashboard doesn\u2019t contain the widgets yet (we have delayed the widget retrieving of 1 second). And even if we move the call in the subscribe, we are not yet ready for the call because the rendering of the args association to the array requires some time. To solve the problem, we can use another component hook, named AfterViewChecked, that is called each time Angular checks the component&#8217;s views and child views:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"552\" data-attachment-id=\"29308\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/68999571-450e-4960-b26a-9c97fd5076ac-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/68999571-450e-4960-b26a-9c97fd5076ac.png?fit=1024%2C552&amp;ssl=1\" data-orig-size=\"1024,552\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"68999571-450e-4960-b26a-9c97fd5076ac\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/68999571-450e-4960-b26a-9c97fd5076ac.png?fit=1024%2C552&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/68999571-450e-4960-b26a-9c97fd5076ac.png?resize=1024%2C552&#038;ssl=1\" alt=\"\" class=\"wp-image-29308\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/68999571-450e-4960-b26a-9c97fd5076ac.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/68999571-450e-4960-b26a-9c97fd5076ac-980x528.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/68999571-450e-4960-b26a-9c97fd5076ac-480x259.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Perfect! No? A suspect must always come in your mind when you work with jQuery plugins: what happens if the data change after the first time and your jQuery code is recalled? Typically it stops to work fine and it also happens in our casehellip; If we add a second setTimeout to our service as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1013\" height=\"768\" data-attachment-id=\"29311\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/4c6658f2-17f4-45e2-b860-4619feb98ccc-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4c6658f2-17f4-45e2-b860-4619feb98ccc.png?fit=1013%2C768&amp;ssl=1\" data-orig-size=\"1013,768\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"4c6658f2-17f4-45e2-b860-4619feb98ccc\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4c6658f2-17f4-45e2-b860-4619feb98ccc.png?fit=1013%2C768&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/4c6658f2-17f4-45e2-b860-4619feb98ccc.png?resize=1013%2C768&#038;ssl=1\" alt=\"\" class=\"wp-image-29311\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4c6658f2-17f4-45e2-b860-4619feb98ccc.png 1013w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4c6658f2-17f4-45e2-b860-4619feb98ccc-980x743.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/4c6658f2-17f4-45e2-b860-4619feb98ccc-480x364.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1013px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">After 5 seconds, our application will show correctly the widgets, but they are not draggable and resizable.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"551\" data-attachment-id=\"29313\" data-permalink=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/attachment\/c4274d30-5e51-4831-a46c-606e08b4cff3-2\/\" data-orig-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/c4274d30-5e51-4831-a46c-606e08b4cff3.png?fit=1024%2C551&amp;ssl=1\" data-orig-size=\"1024,551\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"c4274d30-5e51-4831-a46c-606e08b4cff3\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/c4274d30-5e51-4831-a46c-606e08b4cff3.png?fit=1024%2C551&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/c4274d30-5e51-4831-a46c-606e08b4cff3.png?resize=1024%2C551&#038;ssl=1\" alt=\"\" class=\"wp-image-29313\" srcset=\"https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/c4274d30-5e51-4831-a46c-606e08b4cff3.png 1024w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/c4274d30-5e51-4831-a46c-606e08b4cff3-980x527.png 980w, https:\/\/blexin.com\/wp-content\/uploads\/2020\/12\/c4274d30-5e51-4831-a46c-606e08b4cff3-480x258.png 480w\" sizes=\"auto, (min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) and (max-width: 980px) 980px, (min-width: 981px) 1024px, 100vw\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">If you have some experience with jQuery, you surely know that the solution is to recall the jQuery call, but first, we need to destroy the previous grid first, to make our code correct. According to the gridstack documentation, the code changes as follows:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.tolist.net\/Storage\/d6559c44-6647-4f0f-9bca-1cfdc44a4451\/Articles\/5c08fa71-33e5-4683-8b48-17320328d1bb.png?w=1080\" alt=\"\"\/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Now it works well! You can find the code on my GitHub page, I created a branch for every step (step1, step2, and step3) and merged the step3 in the master at this address:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-rich is-provider-embed-handler wp-block-embed-embed-handler\"><div class=\"wp-block-embed__wrapper\">\n<a href=\"https:\/\/github.com\/apomic80\/dashboard\" rel=\"nofollow\">https:\/\/github.com\/apomic80\/dashboard<\/a>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">I hope this post could be useful for you, not only for the dashboard implementation, but also to integrate other jQuery plugins.&nbsp;<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">See you soon.<\/p>\n\n\n\n\n","protected":false},"excerpt":{"rendered":"<p>How to use component in Angular to create a dashboard with legacy JavaScript libraries<\/p>\n","protected":false},"author":196716248,"featured_media":29247,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"off","_et_pb_old_content":"","_et_gb_content_width":"","_coblocks_attr":"","_coblocks_dimensions":"","_coblocks_responsive_height":"","_coblocks_accordion_ie_support":"","_crdt_document":"","inline_featured_image":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false},"categories":[688637524],"tags":[688637390,688637448],"class_list":["post-29317","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog-en","tag-angular-en","tag-vscode-en"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Angular Advanced Components: how to create a dashboard - Blexin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular Advanced Components: how to create a dashboard - Blexin\" \/>\n<meta property=\"og:description\" content=\"How to use component in Angular to create a dashboard with legacy JavaScript libraries\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/\" \/>\n<meta property=\"og:site_name\" content=\"Blexin\" \/>\n<meta property=\"article:published_time\" content=\"2018-10-23T22:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2021-05-20T17:30:53+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"552\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Michele Aponte\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Michele Aponte\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/\"},\"author\":{\"name\":\"Michele Aponte\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\"},\"headline\":\"Angular Advanced Components: how to create a dashboard\",\"datePublished\":\"2018-10-23T22:00:00+00:00\",\"dateModified\":\"2021-05-20T17:30:53+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/\"},\"wordCount\":1341,\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1\",\"keywords\":[\"Angular\",\"VScode\"],\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/\",\"name\":\"Angular Advanced Components: how to create a dashboard - Blexin\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1\",\"datePublished\":\"2018-10-23T22:00:00+00:00\",\"dateModified\":\"2021-05-20T17:30:53+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#primaryimage\",\"url\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1\",\"contentUrl\":\"https:\\\/\\\/i0.wp.com\\\/blexin.com\\\/wp-content\\\/uploads\\\/2020\\\/12\\\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1\",\"width\":1024,\"height\":552},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/blog-en\\\/angular-advanced-components-how-to-create-a-dashboard\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/blexin.com\\\/en\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular Advanced Components: how to create a dashboard\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#website\",\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/\",\"name\":\"Blexin\",\"description\":\"Con noi \u00e8 semplice\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/blexin.com\\\/en\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/blexin.com\\\/en\\\/#\\\/schema\\\/person\\\/cdc5540c3b6edcacd8d760669e797005\",\"name\":\"Michele Aponte\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g\",\"caption\":\"Michele Aponte\"},\"url\":\"https:\\\/\\\/blexin.com\\\/en\\\/author\\\/michele-aponteblexin-com\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular Advanced Components: how to create a dashboard - Blexin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/","og_locale":"en_US","og_type":"article","og_title":"Angular Advanced Components: how to create a dashboard - Blexin","og_description":"How to use component in Angular to create a dashboard with legacy JavaScript libraries","og_url":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/","og_site_name":"Blexin","article_published_time":"2018-10-23T22:00:00+00:00","article_modified_time":"2021-05-20T17:30:53+00:00","og_image":[{"width":1024,"height":552,"url":"https:\/\/i1.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1","type":"image\/png"}],"author":"Michele Aponte","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Michele Aponte","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#article","isPartOf":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/"},"author":{"name":"Michele Aponte","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005"},"headline":"Angular Advanced Components: how to create a dashboard","datePublished":"2018-10-23T22:00:00+00:00","dateModified":"2021-05-20T17:30:53+00:00","mainEntityOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/"},"wordCount":1341,"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1","keywords":["Angular","VScode"],"articleSection":["Blog"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/","url":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/","name":"Angular Advanced Components: how to create a dashboard - Blexin","isPartOf":{"@id":"https:\/\/blexin.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#primaryimage"},"image":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1","datePublished":"2018-10-23T22:00:00+00:00","dateModified":"2021-05-20T17:30:53+00:00","author":{"@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005"},"breadcrumb":{"@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#primaryimage","url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1","contentUrl":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1","width":1024,"height":552},{"@type":"BreadcrumbList","@id":"https:\/\/blexin.com\/en\/blog-en\/angular-advanced-components-how-to-create-a-dashboard\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/blexin.com\/en\/"},{"@type":"ListItem","position":2,"name":"Angular Advanced Components: how to create a dashboard"}]},{"@type":"WebSite","@id":"https:\/\/blexin.com\/en\/#website","url":"https:\/\/blexin.com\/en\/","name":"Blexin","description":"Con noi \u00e8 semplice","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blexin.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/blexin.com\/en\/#\/schema\/person\/cdc5540c3b6edcacd8d760669e797005","name":"Michele Aponte","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/32138aff568f2063b34d27a23cef27e09f3159bfcadea5ea05599c499cf4342f?s=96&d=identicon&r=g","caption":"Michele Aponte"},"url":"https:\/\/blexin.com\/en\/author\/michele-aponteblexin-com\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/blexin.com\/wp-content\/uploads\/2020\/12\/0b2fdd00-192a-4095-b0bc-627097e78f0e.png?fit=1024%2C552&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcyUBx-7CR","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/29317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/users\/196716248"}],"replies":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/comments?post=29317"}],"version-history":[{"count":6,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/29317\/revisions"}],"predecessor-version":[{"id":32019,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/posts\/29317\/revisions\/32019"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media\/29247"}],"wp:attachment":[{"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/media?parent=29317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/categories?post=29317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blexin.com\/en\/wp-json\/wp\/v2\/tags?post=29317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}