<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jan Hommes</title>
    <description>The latest articles on DEV Community by Jan Hommes (@janhommes).</description>
    <link>https://dev.to/janhommes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F337853%2F2a7f4812-7ef8-4497-ba74-ff8d30ab7d83.png</url>
      <title>DEV Community: Jan Hommes</title>
      <link>https://dev.to/janhommes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/janhommes"/>
    <language>en</language>
    <item>
      <title>Who does even need Microfronteds?</title>
      <dc:creator>Jan Hommes</dc:creator>
      <pubDate>Mon, 25 Sep 2023 19:36:54 +0000</pubDate>
      <link>https://dev.to/janhommes/who-does-even-need-microfronteds-49i2</link>
      <guid>https://dev.to/janhommes/who-does-even-need-microfronteds-49i2</guid>
      <description>&lt;p&gt;I lately have seen a lot of articles emerging around Microfrontends and how to implement them. Sadly, most of them don't answer a simple question: &lt;em&gt;Who does even need Microfrontends?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Before I want to answer this question, let's do a small recap on what a Microfrontend is and what not. A Microfrontend is tightly coupled to Microservice (who would have guessed that 😜). Here, I do not mean the natural coupling of a Frontend to a Backend, but more of the design pattern of a Microservice. By definition, Microservices have three core values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are loosely coupled.&lt;/li&gt;
&lt;li&gt;They can be deployed anywhere and standalone.&lt;/li&gt;
&lt;li&gt;They can scale well.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These core values led to the Microservices popularity as they helped to migrate or avoid a monolithic architecture style where everything depended on each other which is hard to scale and maintain. &lt;br&gt;
The same goes for frontends: If you end up (like me) building a huge frontend application with many features, you find yourself in a maintenance and responsibility hell (regardless of how well you test). Microfronends help to avoid this, by sticking to the core values of microservices (loose coupling, easily deployable, good scalability). Therefore they usually have one shell application and multiple remotes. The shell applications host those remotes (maybe one at a time, or multiple at a time). They are mostly loaded on runtime. You then share certain dependencies (like a common framework) and can load it from different servers. That mostly s serves the three core values of Microservices:&lt;/p&gt;

&lt;p&gt;✅ loosely coupled: The shell and remote need to work on their own. You can share libs via e.g. Module federation.&lt;br&gt;
✅ deployable anywhere: As it's just static files, any Webserver can easily serve the files.&lt;br&gt;
✅ scales well: Webserver can be easily scale horizontal. Additional the teams working on them can scale too, as any team can focus on the domain of the microfrontend.&lt;/p&gt;

&lt;p&gt;The main difference to Microservices lies in the weight of these 3 factors: For a frontend it is much easier to scale and deploy easily, while it is much harder to be loosely coupled. A simple example: Imagine two product teams, one working on the product listing of an e-commerce website, while the other are working on the search bar at the top. Now imagine, the UX designers decide to update the design principles and the search team adopts them faster than the product listing team. The whole website could look out of place (recently happened on the twitter renaming to X).&lt;/p&gt;

&lt;p&gt;This gives already a hint on who really needs Microfrontends: As long as you are a one-man show or a small team, you should definitely avoid using a Microfrontend architecture at all. It just brings complexity overhead, which you should avoid in smaller teams. Even if you consider your teams might scale at a certain time, you should invest more in a domain-driven decoupling (maybe in different libs in a monorepo) than a Microfrontend architecture.&lt;/p&gt;

&lt;p&gt;So, who needs in the end Microfrontends? In my experience there are only two types of projects that needs such an architecture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Huge development teams (+3 teams on the front end) that need clear structures and consistency.&lt;/li&gt;
&lt;li&gt;Applications that should be extendable by external plugins. For example, a dashboard that can be extended by external widgets.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If your application/website does not fall into one of the above sections, simply &lt;strong&gt;do not consider a Microfrontend&lt;/strong&gt; architecture. Try to split your frontends into domain-specific sections and serve them in a classical way. Use style guides and shared libs to ensure consistency.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;About me: I have been building a Microfrontend architecture since 2019 for Cumulocity (read more about it &lt;a href="https://tech.forums.softwareag.com/t/the-power-of-micro-frontends-how-to-dynamically-extend-cumulocity-iot-frontends/266665"&gt;here&lt;/a&gt;). Contact me if you want to discuss Microfrontend architectures or any related work.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>noNPM - node packages for micro frontends</title>
      <dc:creator>Jan Hommes</dc:creator>
      <pubDate>Wed, 07 Dec 2022 19:47:14 +0000</pubDate>
      <link>https://dev.to/janhommes/nonpm-node-packages-for-micro-frontends-20kh</link>
      <guid>https://dev.to/janhommes/nonpm-node-packages-for-micro-frontends-20kh</guid>
      <description>&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I build noNPM (&lt;strong&gt;n&lt;/strong&gt;ot &lt;strong&gt;o&lt;/strong&gt;nly NPM) a node package server that serves the content of any package. It's like unpkg.com, but tries to avoid the issues around it. &lt;/p&gt;

&lt;p&gt;Unlike unpkg.com, the packages need to opt-in by adding a &lt;code&gt;serve&lt;/code&gt; property. Additional noNPM can be used in a local environment by running &lt;code&gt;npx @no-npm/cli&lt;/code&gt; and serve all packages.&lt;br&gt;
For demo purposes, also the cloud offering at noNPM.io serving currently all packages. Try for example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://noNPM.io/react" rel="noopener noreferrer"&gt;https://noNPM.io/react&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can replace &lt;code&gt;react&lt;/code&gt; with any npm package&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Go to &lt;a href="https://noNPM.io" rel="noopener noreferrer"&gt;https://noNPM.io&lt;/a&gt; and you can search for all already used packages. You might notice that the base URL redirects you to &lt;code&gt;https://nonpm.io/@no-npm/web/&amp;lt;&amp;lt;version&amp;gt;&amp;gt;/dist/web/&lt;/code&gt;. That works, because I simply serve the web interface also directly from &lt;a href="https://www.npmjs.com/package/@no-npm/web" rel="noopener noreferrer"&gt;npm&lt;/a&gt;. You can change the version number of the package to see older versions. For example, to see the first (not working) iteration of the web interface open &lt;a href="http://nonpm.io/@no-npm/web@0.1.0" rel="noopener noreferrer"&gt;https://nonpm.io/@no-npm/web@0.1.0&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This exactly is the reason why I build noNPM. It should allow to serve immutable web applications for a &lt;a href="https://martinfowler.com/articles/micro-frontends.html" rel="noopener noreferrer"&gt;micro frontend architecture&lt;/a&gt;, so that teams can work better together on different features that get combined into one application without breaking them. With noNPM you can rely on the fact that &lt;strong&gt;every package is versioned&lt;/strong&gt;, you can &lt;strong&gt;resolve packages via tags or versions&lt;/strong&gt; and every &lt;strong&gt;version does not change&lt;/strong&gt;. This allows to avoid running in a &lt;em&gt;"version-hell"&lt;/em&gt; when using a micro frontend architecture.&lt;/p&gt;
&lt;h3&gt;
  
  
  Category Submission:
&lt;/h3&gt;

&lt;p&gt;Search No More: As npm host more then 2 million packages, we needed a fast search. We leverage MongoDB to store the package meta information and search for them.&lt;/p&gt;
&lt;h3&gt;
  
  
  App Link
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://nonpm.io" rel="noopener noreferrer"&gt;noNPM.io&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91yee9jm8gqiu7pr0t22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91yee9jm8gqiu7pr0t22.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2tems6h5vzz5ds6q8tq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2tems6h5vzz5ds6q8tq.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Description
&lt;/h3&gt;

&lt;p&gt;While NPM is great, with upcoming micro frontends trend, NPM does not serve the necessary of remote modules. While one could argue, that anyone could serve simply static files, the ability of NPM to manage versions, tagging and disallow reusing versions is exactly what is needed to run a micro frontend architecture. The following examples all resolve different versions of the &lt;code&gt;@no-npm/example&lt;/code&gt; package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remoteHello&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://nonpm.io/@no-npm/example@1.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remoteHello&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://nonpm.io/@no-npm/example@^1.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remoteHello&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://nonpm.io/@no-npm/example@~1.0.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remoteHello&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://nonpm.io/@no-npm/example@latest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;remoteHello&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://nonpm.io/@no-npm/example@beta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Link to Source Code
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/janhommes/noNPM" rel="noopener noreferrer"&gt;https://github.com/janhommes/noNPM&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissive License
&lt;/h3&gt;

&lt;p&gt;MIT&lt;/p&gt;

&lt;h2&gt;
  
  
  Background
&lt;/h2&gt;

&lt;p&gt;I work currently on a micro frontend architecture and was wondering if we could leverage NPM to simply reuse the versioning and tagging possibilities. &lt;/p&gt;

&lt;h3&gt;
  
  
  How I built it
&lt;/h3&gt;

&lt;p&gt;The REST interface is build with nestjs and hosted on Google Kubernetes Engine. On first request to a package which is unknown to the platform it will be extracted to a file storage. The metadata of a package is stored into MongoDB. Atlas search is used to find the package in the web interface.&lt;/p&gt;

&lt;p&gt;The web-interface is build in Angular. It is uploaded to &lt;a href="https://npmjs.com/@no-npm/web" rel="noopener noreferrer"&gt;npm&lt;/a&gt; and as the REST interface can serve npm packages it also can serve this package. It queries the REST interface &lt;code&gt;browse/search&lt;/code&gt; endpoint for showing the search-results in an auto-complete.&lt;/p&gt;

&lt;p&gt;A CLI exist to use the same ability locally. If used locally, noNPM uses a simple JSON file to store the meta information of the packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources/Info
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://martinfowler.com/articles/micro-frontends.html" rel="noopener noreferrer"&gt;More information about microfrontends&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://unpkg.com" rel="noopener noreferrer"&gt;unpkg.com inspired this project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>atlashackathon22</category>
      <category>microfrontend</category>
      <category>npm</category>
    </item>
    <item>
      <title>noREST - schema-less REST API</title>
      <dc:creator>Jan Hommes</dc:creator>
      <pubDate>Mon, 28 Sep 2020 18:14:08 +0000</pubDate>
      <link>https://dev.to/janhommes/norest-schema-less-rest-api-5bi3</link>
      <guid>https://dev.to/janhommes/norest-schema-less-rest-api-5bi3</guid>
      <description>&lt;p&gt;I finally got the courage to publish my side project which I am working on for nearly one year. It's called noREST -&amp;gt; and, as the name implies, the name is referring indirect to noSQL. That's because the concepts are quite similar. Like noSQL, the differentiating is the non-schema layout of noREST. So basically it's an API without a fixed interface. You might question, what do I need an API without an interface for? It's like buying a house without a contract, or not?&lt;/p&gt;

&lt;p&gt;You might be right: Having no fixed schema/interface on an API mostly sounds strange and does somehow contradict the intention of an API. APIs are designed to give the programmer an interface that defines how the data needs to be shaped. Like a purchase contract when buying a house: Everything needs to be in place, there are rules and rights that need to be followed and there is a notary who ensures the contract. If something in the contract is invalid the deal will not be signed. &lt;/p&gt;

&lt;p&gt;However, even buying a coffee is already a purchase contract. And they mostly follow the same rules: The barista is offering the coffee and you are willing in on the contract by simply stating "Can I get grande latte chocolate whatever thingy". As soon as the exchange of money and "coffee" is done, the deal is closed. No notary, no fixed contract, no signing. Still a valid purchase contract.&lt;/p&gt;

&lt;p&gt;The same goes for APIs: Sometimes the need for a simpler and easier contract then traditional schema bounded APIs is a valid use case. Especially when it comes to server-side-rendering or when you simply just scratching an app and want to focus on building the UI first.&lt;/p&gt;

&lt;p&gt;That is what noREST is built for. By simply calling &lt;code&gt;npx @norest/cli&lt;/code&gt; you get a REST-full server, which follows very simple rules (like buying a coffee). These rules are designed to allow rapid development. One of the core rules is, that there is no schema. Endpoints are defined by so-called &lt;code&gt;index fragments&lt;/code&gt; which are simply data itself with a special prefix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /api
{
   "name": "foo",
   "price": 10,
   "#_products": {}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Is the above data posted to the API, the data is requestable via a &lt;code&gt;GET /api/products&lt;/code&gt; simply because the index fragment &lt;code&gt;"#_products": {}&lt;/code&gt; is added to it. That way you can store any data to the API and still using it in a RESTfull manner. Like noSQL just for APIs. Simply called noREST.&lt;/p&gt;

&lt;p&gt;What most people don't know: noSQL stands for &lt;strong&gt;not only&lt;/strong&gt; SQL. Meaning that it allows more than just querying data. The same goes for noREST. Currently, there is authentication, metadata, references, and WebSocket support out of the box and more is planned as plugins. &lt;/p&gt;

&lt;p&gt;If you like the idea, you can see all that in action on the small interactive playground at &lt;a href="https://notonly.rest"&gt;https://notonly.rest&lt;/a&gt;. If you want to dig deeper into noREST, the best way to start is the &lt;a href="https://github.com/janhommes/noREST"&gt;GitHub page&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Thanks for reading about my little side project. I would be happy to hear your thoughts about this?&lt;/p&gt;

</description>
      <category>node</category>
      <category>rest</category>
      <category>nosql</category>
      <category>typescript</category>
    </item>
    <item>
      <title>The power of structural directives</title>
      <dc:creator>Jan Hommes</dc:creator>
      <pubDate>Mon, 29 Jun 2020 19:22:38 +0000</pubDate>
      <link>https://dev.to/janhommes/the-power-of-structural-directives-23fg</link>
      <guid>https://dev.to/janhommes/the-power-of-structural-directives-23fg</guid>
      <description>&lt;p&gt;&lt;strong&gt;Structural directives are a very powerful tool in Angular, but up till now, I rarely used them. The build-in ones are suitable for nearly every use-case I faced so far. &lt;br&gt;
 But lately, I reimplemented the &lt;a href="https://angular.io/api/common/NgForOf"&gt;*ngFor&lt;/a&gt; with a custom implementation of mine to implement an infinity scroll alternative. That was my personal "wow" effect and for the first time, I understood the full power of structural directives. This article should outline this power, but first, to the basics: What is a structural directive?&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is a structural directive?
&lt;/h2&gt;

&lt;p&gt;I could not better phrase it then the angular documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Structural directives are responsible for HTML layout. They shape or reshape the DOM's structure, typically by adding, removing, or manipulating elements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So basically: Every time you want to restructure something in the DOM you use a structural directive. The most commonly used ones are &lt;code&gt;*ngIf&lt;/code&gt; or &lt;code&gt;*ngFor&lt;/code&gt;, which represent a condition or a loop on the template. Here is an example of how you could use a &lt;code&gt;*ngIf&lt;/code&gt; on an Angular template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"toggle = !toggle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Show
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"toggle"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  I'm added or removed from the DOM with a structural directive.
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing really new about this. But, what mostly is unknown: You can build your &lt;strong&gt;own&lt;/strong&gt; structural directive. Let's try to reimplement the &lt;code&gt;*ngIf&lt;/code&gt; next.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing you're own structural directive
&lt;/h2&gt;

&lt;p&gt;Basically it's plain easy to write your own structural directive, as it is just a normal directive. You just need to create a directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Directive&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Directive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[superIf]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SuperIfDirective&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;init&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you can already add it as a structural directive &lt;strong&gt;and&lt;/strong&gt; as a normal directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*superIf&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;superIf&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you try that plain example, you will find only one &lt;code&gt;Test&lt;/code&gt; output on your app. But the directive was actual initialized two times:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/angular-onbhnc?view=both&amp;amp;file=src/app/app.component.html" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That is because the &lt;code&gt;*&lt;/code&gt; is syntactic sugar which will wrap the component where this element is attached within the template. So, in fact the following is the same:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ng-template&lt;/span&gt; &lt;span class="err"&gt;[&lt;/span&gt;&lt;span class="na"&gt;superIf&lt;/span&gt;&lt;span class="err"&gt;]&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Test&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ng-template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can verify this by using our above &lt;code&gt;*ngIf&lt;/code&gt; example. If you change the &lt;code&gt;*ngIf&lt;/code&gt; to use the above layout, it will still work the same:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/angular-kmmhk1?view=both&amp;amp;file=src/app/app.component.html" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That's basically all of the mystery of structural directives. They are just syntax sugar for writing cleaner templates. As soon as you have access to the &lt;code&gt;ng-template&lt;/code&gt; you can manipulate the DOM to your need. The next chapter will show how you roll your own ngIf.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building your own ngIf
&lt;/h2&gt;

&lt;p&gt;It's really not that hard to build your own ngIf as soon as you understand the basics: A structural directive is syntactic sugar for a directive that is wrapped in an &lt;code&gt;ng-template&lt;/code&gt;. That is why you can simply inject the template reference to your directive and use it to attach it to your view. &lt;/p&gt;

&lt;p&gt;First, we need to add the &lt;code&gt;TemplateRef&lt;/code&gt; and &lt;code&gt;ViewContainerRef&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Directive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Input&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Directive&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;[superIf]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;SuperIfDirective&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;tpl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;vcr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ViewContainerRef&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ViewContainer&lt;/code&gt; reference is the point, where your structural directive is placed in the current view. Think of it as an invisible placeholder, which you can append any template to. This is what we are doing in the next step:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;superIf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vcr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// 1&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// 2&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vcr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createEmbeddedView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tpl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The setter with the same name as the directive will ensure that we get the value that is assigned to our directive. Then we simply always clear the view when the setter is called (1), afterward we check if the expression is truly (2) and if yes, we create the template into our view container "placeholder" (3). The result works exactly as the *ngIf we know of:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/angular-hjhtfj?view=both&amp;amp;file=src/app/superIf.directive.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Easy, right? You might know that there are more functions. For example, there is an &lt;code&gt;else&lt;/code&gt; in the default &lt;code&gt;*ngIf&lt;/code&gt;. Also, this is fairly easy to implement when you know of the ability to pass multiple values to a directive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;superIfElse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TemplateRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elseTemplate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to pass an else template to the directive either with the structural directive micro syntax: &lt;code&gt;&amp;lt;div *superIf="toggle; else notTrue"&amp;gt;&lt;/code&gt;. &lt;br&gt;
Or, as this is just sugar, we can also use the directive approached on a template: &lt;code&gt;&amp;lt;ng-template [superIf]="toggle" [superIfElse]="notTrueDirective"&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What is left is to check if the else template is set. If it is, and the expression is false, we attach this template instead of the one the directive is placed on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;superIf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vcr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expression&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vcr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createEmbeddedView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tpl&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elseTemplate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vcr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createEmbeddedView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;elseTemplate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's all, you now created an &lt;code&gt;*ngIf&lt;/code&gt; replacement. You can see the full example &lt;a href="https://stackblitz.com/edit/angular-hghkc9?file=src%2Fapp%2FsuperIf.directive.ts"&gt;here&lt;/a&gt;. If this is useful? I don't think so. Why reinventing the wheel? But it's super useful to understand the concept of structural directives. Next up we will build an actual useful directive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing something useful
&lt;/h2&gt;

&lt;p&gt;So rebuilding the build-in directives is nice for understanding the concept but it doesn't bring any benefit. This chapter tries to implement something easy and at the same time useful. &lt;br&gt;
Therefore we are going to develop an &lt;strong&gt;usefulAssign&lt;/strong&gt; directive which should allow to write cleaner templates. The problem is mostly known to Angular developers: When you request an observable which resolves to an object you often end up in reusing the async pipe over and over again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  min: {{(interval$ | async).min}}&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  s: {{(interval$ | async).s}}&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  ms: {{(interval$ | async).ms}}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That looks strange and gets very confusing soon. The idea is to use a directive for this to bind to an implicit variable. Then you can use this variable instead of reusing the async pipe over and over again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;*usefulAssign=&lt;/span&gt;&lt;span class="s"&gt;"interval$ | async; let timer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  min: {{timer.min}}&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  s: {{timer.s}}&lt;span class="nt"&gt;&amp;lt;br&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  ms: {{timer.ms}}
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result: Much cleaner templates and less async pipe usage. The implementation is quite easy, we just need to add a context object to the &lt;code&gt;createEmbeddedView&lt;/code&gt; function and the first implicit variable gets the &lt;code&gt;value&lt;/code&gt; assigned. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;$implicit&lt;/code&gt; is a special type of context, which doesn't need an assignment. You can add more which need to be assigned in the template (e.g. &lt;code&gt;interval$ | async; let foo = bar&lt;/code&gt;. If &lt;code&gt;bar&lt;/code&gt; is defined in the context as &lt;code&gt;{ bar: 'foobar' }&lt;/code&gt; then the foo variable contains the &lt;code&gt;foobar&lt;/code&gt; string).&lt;/p&gt;

&lt;p&gt;The directive itself then looks like this:&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://stackblitz.com/edit/angular-d9dvdv?view=both&amp;amp;file=src/app/usefulAssign.directive.ts" width="100%" height="500"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;As you can see in this example, the value passed to the directive is assigned as an implicit context (1) and therefore available in the template. This allows many different approaches as you can pass any context which you can then reuse in the template easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else?
&lt;/h2&gt;

&lt;p&gt;So this article is just a short introduction and should show what structural directives can do. This is just the tip of the iceberg and some more ideas are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using it as an infinity scroll solution in combination with paged REST API and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API"&gt;Intersection Observable API&lt;/a&gt;. Imagine using &lt;code&gt;*infinityFor="let image of images"&lt;/code&gt; and you get infinity scrolling without doing anything more, by simply using the same approach as &lt;code&gt;*ngFor&lt;/code&gt; and an additional hidden "load-more" component at the end of the list. This loads more data as soon as it is intersected.&lt;/li&gt;
&lt;li&gt;Templating for more complex components like tables (like Material CDK does it).&lt;/li&gt;
&lt;li&gt;dynamic components loading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, it is always questionable to reinvent the wheel. Don't use a custom structural directive, if a build-in can do the same job.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
