<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Matt Vaughn on Medium]]></title>
        <description><![CDATA[Stories by Matt Vaughn on Medium]]></description>
        <link>https://medium.com/@angularlicious?source=rss-d1401157ae8c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*lg2mbl06fF9S4rc7ielw8Q.jpeg</url>
            <title>Stories by Matt Vaughn on Medium</title>
            <link>https://medium.com/@angularlicious?source=rss-d1401157ae8c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 21:23:49 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@angularlicious/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Angular Application Version Check with Nx Executor]]></title>
            <link>https://medium.com/angularlicious/angular-application-version-check-with-nx-executor-828dd650e86b?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/828dd650e86b</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Wed, 13 Nov 2024 23:15:03 GMT</pubDate>
            <atom:updated>2024-11-13T23:15:03.159Z</atom:updated>
            <content:encoded><![CDATA[<blockquote><em>&quot;Versioning is like a check-up for your app — if you don’t stay current, you risk delivering outdated content to users.”</em></blockquote><p>Ensuring that users of your Angular application have the latest features, bug fixes, and security patches is critical for a smooth user experience. This post will explain a version-checking solution for Angular applications within an Nx workspace, focusing on keeping the app synchronized with the latest version hosted on the server. We’ll cover each layer of the C4 Model, from Context down to Sequence, to illustrate the technical design. At the end, we’ll discuss how Service Workers and Server-Side Rendering (SSR) could further strengthen this solution.</p><p>There are (2) aspects to consider. The build process will need to retrieve and use a specific version for the comparison. The runtime Angular application will need to be able to retrieve the local version information and compare it to what is currently deployed (i.e., production).</p><h3>Build System</h3><h3>Build Context View</h3><p>In the Context View, we look at the big picture — who interacts with the system and the primary entities involved. This diagram shows the key actors and their relationships in the version-checking <a href="http://process.in/">process.In</a> this view, we identify the external systems and users that interact with the version-checking process, providing a high-level overview of the system’s environment and its boundaries.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OOCWDdj281MopHsLfBgpWQ.png" /></figure><p><strong>Key Actors:</strong></p><ul><li>User: The person accessing the Angular application via a browser. They expect the application to be up-to-date and functional.</li><li>Angular Application: The client-side application running in the user’s browser. It needs to check for updates to ensure it has the latest version.</li><li>Cloud Endpoint: The server environment where the application and version information (version.json) are hosted.</li><li>Application Host: Represents the current application instance in production, exposed via the Cloud Endpoint.</li></ul><p><strong>Summary of Interactions:</strong></p><ul><li>The User interacts with the Angular Application through their browser.</li><li>The Angular Application interacts with the Cloud Endpoint to retrieve the latest version information, ensuring it has the most recent version of version.json.</li></ul><h3>Build Container View</h3><p>The Container View breaks down the main pieces of the system and how they interact to ensure version consistency. It includes the Angular application, its services, and the versioning files hosted on the cloud.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kfdScH15iPfDH9ojtOFL4w.png" /></figure><p><strong>Main Containers:</strong></p><ul><li>Angular Application: The front-end application that the user accesses.</li><li>Build Script/Workflow: Handles the build process and includes the version-checking logic.</li><li>Distribution Output: The final build output containing application assets, including the version.json file.</li><li>Cloud Endpoint: Hosts the application and the version.json file, providing an endpoint for the Angular application to check the current version.</li></ul><p><strong>Process Overview</strong></p><ul><li>During each build, the Build Script/Workflow generates and packages a version.json file based on the version in package.json.</li><li>The version.json file is added to the Distribution Output and deployed to the Cloud Endpoint.</li><li>The Angular Application can request version.json from the Cloud Endpoint to validate its version against the server’s latest version.</li></ul><h3>Build Component View</h3><p>The Component View drills down into the specific services and logic within the Angular application that handle version checking. It describes how each piece contributes to determining if the app in the user’s browser is the latest version.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Og9hGf6-xQIM2LVEDxhI_A.png" /></figure><p>Core Components:</p><ul><li>Configuration Service: Retrieves and stores configuration settings, including the current application version.</li><li>Version Check Service: Manages the version-checking process by periodically or on-demand fetching version.json from the Cloud Endpoint. It compares the server version to the locally running version.</li><li>Notification System: Notifies the user if the application is outdated and suggests reloading to update to the latest version.</li></ul><p>Component Interactions:</p><ul><li>The Angular Application initializes the Configuration Service and the Version Check Service on startup.</li><li>The Version Check Service can be configured to perform scheduled checks or triggered on-demand by the user. It retrieves version.json from the Cloud Endpoint and compares it to the current version stored by the Configuration Service.</li><li>If a version mismatch is detected, the Notification System alerts the user to reload the application.</li></ul><h3>Build Sequence Diagram</h3><p>The Sequence Diagram illustrates the step-by-step interactions among the components to manage version checking. It shows how the Angular application, through its services, checks for updates and notifies the user as needed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zGSjA6A40sVEA9Z4EDy1cA.png" /></figure><ol><li>Build-Time Version Determination:</li></ol><ul><li>The Build Script triggers the versioning process using an Nx Executor.</li><li>The Nx Version Executor retrieves the version from package.json and updates version.json in the application assets.</li><li>The application is built, and version.json is included in the Distribution Output, which is then deployed to the Cloud Endpoint.</li></ul><p>2. Run-Time Version Check:</p><ul><li>The Version Check Service in the Angular application fetches the version.json file from the Cloud Endpoint.</li><li>It compares the local and server versions. If a mismatch is detected, the user is notified and prompted to reload the app.</li></ul><h3>Nx Executor for Version Management</h3><p>To update the executor to create a JSON file in the target project’s assets folder and provide a sample configuration in a project.json file, follow these steps:</p><h4>Update the Executor to Create a JSON File</h4><ol><li>Modify the executor: Update your executor code to write the version information to a JSON file in the target project’s assets directory.</li></ol><pre>import { ExecutorContext } from &#39;@nrwl/devkit&#39;;<br>import * as fs from &#39;fs&#39;;<br>import * as path from &#39;path&#39;;<br><br>interface VersionCheckOptions {<br>  project: string;<br>}<br><br>export default async function runExecutor(<br>  options: VersionCheckOptions,<br>  context: ExecutorContext<br>) {<br>  try {<br>    const workspaceRoot = context.root;<br>    const projectRoot = context.workspace.projects[options.project].root;<br>    const packageJsonPath = path.join(workspaceRoot, &#39;package.json&#39;);<br>    const assetsFolder = path.join(workspaceRoot, projectRoot, &#39;assets&#39;);<br>    <br>    if (!fs.existsSync(assetsFolder)) {<br>      fs.mkdirSync(assetsFolder, { recursive: true });<br>    }<br>    <br>    const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, &#39;utf8&#39;));<br>    const versionInfo = { version: packageJson.version };<br><br>    const outputFilePath = path.join(assetsFolder, &#39;version-info.json&#39;);<br>    fs.writeFileSync(outputFilePath, JSON.stringify(versionInfo, null, 2));<br><br>    console.log(`Version info written to ${outputFilePath}`);<br>    <br>    return { success: true };<br>  } catch (error) {<br>    console.error(&#39;Failed to write version info:&#39;, error);<br>    return { success: false };<br>  }<br>}</pre><h4>Configure the Executor in executors.json</h4><p>Ensure your executors.json is correctly set up:</p><pre>{<br>  &quot;executors&quot;: {<br>    &quot;version-check&quot;: {<br>      &quot;implementation&quot;: &quot;./src/executors/version-check/executor&quot;,<br>      &quot;schema&quot;: &quot;./src/executors/version-check/schema.json&quot;,<br>      &quot;description&quot;: &quot;Create a JSON file with version information in the project&#39;s assets folder&quot;<br>    }<br>  }<br>}</pre><h4>Create the Executor Schema</h4><p>Create a schema.json file (at libs/your-plugin-name/src/executors/version-check/) to define the options your executor will receive:</p><pre>{<br>  &quot;type&quot;: &quot;object&quot;,<br>  &quot;properties&quot;: {<br>    &quot;project&quot;: {<br>      &quot;type&quot;: &quot;string&quot;,<br>      &quot;description&quot;: &quot;The name of the project where the JSON file will be created.&quot;<br>    }<br>  },<br>  &quot;required&quot;: [&quot;project&quot;]<br>}</pre><h4>Sample Configuration in project.json</h4><p>Here’s how you can configure a target to use this executor in a project.json file:</p><pre>{<br>  &quot;name&quot;: &quot;your-project-name&quot;,<br>  &quot;root&quot;: &quot;apps/your-project-name&quot;,<br>  &quot;sourceRoot&quot;: &quot;apps/your-project-name/src&quot;,<br>  &quot;projectType&quot;: &quot;application&quot;,<br>  &quot;targets&quot;: {<br>    &quot;check-version&quot;: {<br>      &quot;executor&quot;: &quot;your-plugin-name:version-check&quot;,<br>      &quot;options&quot;: {<br>        &quot;project&quot;: &quot;your-project-name&quot;<br>      }<br>    }<br>  }<br>}</pre><h4>Run the Executor</h4><p>You can now execute this target in your Nx workspace or in an automation script (e.g., CI/CD pipeline) to update the version information.</p><pre>npx nx run your-project-name:check-version</pre><p>This setup will create a version-info.json inside the assets folder of the specified project, containing the version information from the root package.json.</p><h3>System Architecture Overview</h3><p>Managing application versioning is essential to provide users with the most up-to-date content. This information will guide you through a version-checking system for Angular applications in an Nx workspace, designed to keep the application in sync with the latest version on the server. We’ll explore each layer of the C4 Model: Context, Container, Component, and Sequence, and discuss future improvements with Service Workers and Server-Side Rendering (SSR).</p><h3>System Context View</h3><p>The Context View provides an overview of the system and its key interactions with users and external systems. Here’s the big picture of how version management works in our setup.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j61Nd9jCkYZB1g7SWt1yrw.png" /></figure><p>Key Actors:</p><ul><li>User: The end-user accessing the Angular application via their browser.</li><li>Angular Application: A single-page web application that runs in the user’s browser.</li><li>Version Check System: Responsible for determining if the application version in the browser matches the version hosted on the server.</li><li>Application Host: The server hosting the current version of the application, including version information in version.json.</li></ul><p>Summary of Interactions:</p><ul><li>The User interacts with the Angular Application, which checks with the Application Host to verify that the application version is up to date.</li><li>The Version Check System retrieves the version from a locally stored version.json file and compares it with the hosted version to ensure consistency.</li></ul><h3>System Container View</h3><p>In the Container View, we break down the main parts of the version-checking system and how they communicate with each other. This level outlines the key services involved in version management.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MLM_BtraVniwQU-SvkaxJw.png" /></figure><p>Main Containers:</p><ul><li>Angular Application: The application itself, which runs in the browser and initiates the version check.</li><li>Configuration Service: A service within the Angular app responsible for managing configuration settings, including version details.</li><li>Version Check Service: Checks the application’s version status against the hosted version on a scheduled or on-demand basis.</li><li>Version Information: Stores the current version information of the application as a JSON asset (version.json).</li><li>Cloud Endpoint: The server where the Angular application and the version information are hosted, making them accessible to the Version Check System.</li></ul><p>Process Overview:</p><ul><li>The Angular Application interacts with the Configuration Service to retrieve initial version details and periodically calls the Version Check Service to fetch the latest version information from the Cloud Endpoint.</li><li>The Version Information file, located on the Cloud Endpoint, provides the reference version. If a mismatch is detected, the system can prompt the user to reload.</li></ul><h3>System Component View</h3><p>The Component View provides a deeper look at the specific services and components that drive version checking within the Angular application. This view focuses on the internal structure and logic of the version-checking process.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ARwM9r6Q4Qs1bzSY9v1slg.png" /></figure><p>Core Components:</p><ul><li>Angular Application: Initializes the Configuration Service and Version Check Service, which are essential to managing and verifying the version.</li><li>Configuration Service: Sets and retrieves configuration settings, storing the current version of the application.</li><li>Version Check Service: A dedicated service for checking the application version. It includes:</li><li>Timer/Schedule: Manages when version checks occur, either at fixed intervals or upon user request.</li><li>Notification System: Notifies the user if a version update is available and prompts a reload.</li><li>Logging: Tracks version check activity for diagnostics and troubleshooting.</li></ul><p>Component Interactions:</p><ul><li>The Angular Application initializes the Configuration Service and the Version Check Service when it starts up.</li><li>The Version Check Service can be triggered on a schedule or on-demand to fetch the version.json from the Cloud Endpoint. If the version in the version.json file on the server differs from the local version, the Notification System alerts the user to reload.</li></ul><h3>System Sequence Diagram</h3><p>The Sequence Diagram shows the step-by-step interactions of the version-checking system components, from initialization to version verification.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Tetql1UJ6cNGcEL-ThRQTg.png" /></figure><ol><li>Application Initialization:</li></ol><ul><li>The Angular Application loads configuration settings through the Configuration Service, which includes the current version information stored locally.</li></ul><p>2. Scheduled or On-Demand Version Check:</p><ul><li>The Version Check Service is initialized and retrieves current version settings.</li><li>The service checks the hosted version information file (version.json) at the Cloud Endpoint to see if a newer version is available.</li></ul><p>3. Version Comparison and Notification:</p><ul><li>If a version mismatch is detected, the Version Check Service triggers the Notification System to prompt the user for a reload.</li><li>Depending on the check (scheduled or on-demand), the system will continue to monitor for updates and notify users as needed.</li></ul><h3>Merits of the Solution</h3><p>This version-checking solution offers several key benefits:</p><ul><li>Automation: Custom Nx executors automate the retrieval and updating of version information, reducing human error and ensuring consistency.</li><li>User Notification: By regularly checking for updates, the application can notify users if a new version is available, enhancing the user experience.</li><li>Configurable Checks: The solution supports both scheduled and on-demand checks, allowing flexibility in how frequently the application verifies its version.</li><li>Simple Deployment: The use of version.json is a lightweight approach that integrates well with standard web hosting, requiring minimal server-side configuration.</li></ul><h3>Proposed Future Path: Service Workers and SSR</h3><p>While the current setup is effective, it has limitations. Service Workers and Server-Side Rendering (SSR) could enhance this solution’s reliability and user experience.</p><h4>Service Workers</h4><p>Service Workers run in the background and can intercept network requests, making them ideal for handling caching and background updates.</p><p>Advantages:</p><ul><li>Automatic Background Updates: Service Workers can detect updates without user interaction, fetching the latest assets in the background.</li><li>Enhanced Caching: Service Workers enable more efficient caching and offline capabilities, improving load times and availability.</li><li>Smooth User Experience: Service Workers can reload the app seamlessly after an update, creating a frictionless experience for users.</li></ul><p>Implementation:</p><ul><li>Angular has built-in support for Service Workers through @angular/service-worker. Configuring a Service Worker to cache assets and periodically check version.json can automate update handling.</li></ul><h4>Server-Side Rendering (SSR)</h4><p>SSR renders the initial page on the server, reducing time-to-interactive and ensuring users receive the latest version upon first load.</p><p>Advantages:</p><ul><li>Improved Performance: SSR decreases load time by delivering pre-rendered HTML, especially beneficial for new users or slow network connections.</li><li>SEO Boost: Pre-rendered pages improve visibility and indexing by search engines.</li><li>Fresh Content on First Load: SSR ensures that users always get the latest version on the first load, preventing cached content issues.</li></ul><p>Implementation</p><ul><li>Angular Universal can be used to set up SSR for an Angular application.</li><li>Combining SSR with Service Workers offers both fast initial loads and background updates.</li></ul><h3>Conclusion</h3><p>This version-checking system offers a robust foundation to ensure users always have the latest version of your Angular application. By leveraging a clear separation of concerns with the Configuration Service, Version Check Service, and Notification System, it provides an effective and maintainable solution. The current setup supports both build-time and run-time checks, maximizing flexibility. Looking ahead, integrating Service Workers and Server-Side Rendering (SSR) can further enhance the system, offering smoother, automated updates, greater reliability, and improved performance.</p><p>These advancements pave the way for an industrial-strength version management approach, minimizing outdated application issues and optimizing user experience.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=828dd650e86b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/angular-application-version-check-with-nx-executor-828dd650e86b">Angular Application Version Check with Nx Executor</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular 17 & Nx 17: Calling Angular CLI Schematics in Nx Generators]]></title>
            <link>https://angularlicious.medium.com/angular-17-nx-17-calling-angular-cli-schematics-in-nx-generators-8a5ca652c9b4?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8a5ca652c9b4</guid>
            <category><![CDATA[angularlicious]]></category>
            <category><![CDATA[matt-vaughn]]></category>
            <category><![CDATA[nx-generators]]></category>
            <category><![CDATA[nx]]></category>
            <category><![CDATA[buildmotion]]></category>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Wed, 22 Nov 2023 19:38:06 GMT</pubDate>
            <atom:updated>2023-11-22T19:38:06.226Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wQ1ldePxYWrz2r6fdxk01w.png" /><figcaption>Nx wants to call Angular for some Schematics.</figcaption></figure><h3>Overview</h3><p>As of Nx version 17, the approach to calling Angular CLI schematics from an Nx Generator has changed. The wrapAngularDevkitSchematic function was part of Nx&#39;s utilities to bridge the gap between the Angular DevKit and Nx&#39;s devkit. However, with newer versions of Nx, this function has been removed as Nx has moved towards a more unified approach.</p><h3>Calling Angular CLI Schematics in Nx v17+</h3><p>To call an Angular CLI schematic from an Nx Generator in Nx v17 and later, you can use the externalSchematic function provided by Angular&#39;s DevKit. Here’s how you can do it:</p><ol><li>Import externalSchematic:</li><li>First, you need to import externalSchematic from @angular-devkit/schematics.</li></ol><pre>import { externalSchematic } from &#39;@angular-devkit/schematics&#39;;</pre><p>3. Call the Schematic in Your Generator:</p><p>Within your Nx generator, you can use externalSchematic to execute an Angular schematic. Here’s an example:</p><pre>import { chain, externalSchematic, Rule } from &#39;@angular-devkit/schematics&#39;;<br><br>export function myNxGenerator(options: any): Rule {<br>  return chain([<br>    // ... other rules or functions<br>    externalSchematic(&#39;@angular/material&#39;, &#39;navigation&#39;, {<br>      // options for the Angular schematic<br>    }),<br>    // ... other rules or functions<br>  ]);<br>}</pre><p>In this example, the externalSchematic function is used to call the Angular Material navigation schematic with specific options.</p><h3>Important Points</h3><ul><li><strong>Dependencies</strong>: Make sure you have the necessary Angular packages installed in your workspace to use their schematics.</li><li><strong>Compatibility</strong>: Ensure that the Angular CLI version in your workspace is compatible with Nx v17.</li><li><strong>Chain with Other Rules</strong>: You can chain this call with other rules or functions in your generator to create complex workflows.</li></ul><h3>Summary</h3><p>In Nx v17 and later, you use the externalSchematic function from Angular&#39;s DevKit to call Angular CLI schematics within Nx generators. This approach provides a seamless way to integrate Angular CLI capabilities into your Nx workspace, enabling the use of a wide range of existing schematics alongside Nx&#39;s powerful tooling.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8a5ca652c9b4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular Components in Enterprise Web Applications: Managing and Simplifying their concerns with UI…]]></title>
            <link>https://medium.com/angularlicious/angular-components-in-enterprise-web-applications-managing-and-simplifying-their-concerns-with-ui-c3c457212ea4?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c3c457212ea4</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Fri, 25 Aug 2023 22:26:57 GMT</pubDate>
            <atom:updated>2023-08-25T22:26:57.884Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h3>Angular Components in Enterprise Web Applications: Managing and Simplifying their concerns with UI Services</h3><h4>Complex applications require more simplicity.</h4><p>In the world of Angular development, components are often considered the bedrock upon which apps are built. Couple this with a layered architecture where you separate the concerns of an application, understanding the responsibilities of an Angular component becomes even more crucial.</p><p>This article aims to address the concern of Angular Components within Enterprise web applications, how to manage and simplify these concerns and, in particular, why the use of UI Services can help mediate these responsibilities, ensuring robust, scalable, and maintainable enterprise-level applications.</p><h4>What Is The Concern Of An Angular Component?</h4><p>Before delving into the specifics of managing an Angular component’s concerns, we must first define what we mean by a ‘concern’. In the context of system design, a ‘concern’ is a particular aspect of the system’s functionality. For an Angular Component, the main concern lies in collecting or displaying information.</p><p>Components are one of the fundamental building blocks of any Angular application, and they serve as a conduit between the template (HTML) and the underlying data (services). In other words, components are responsible for rendering data and handling user interaction. They form the user interface logic which serve distinct purposes within the user interface, and consequently, they should only be concerned with their specific role in this domain.</p><pre>@Component({<br>    selector: &#39;app-user-detail&#39;,<br>    templateUrl: &#39;user-detail.component.html&#39;<br>  })<br>  export class UserDetailComponent {<br>    user$: Observable&lt;User&gt;;<br><br>    constructor(private userService: UserService) {}<br><br>    ngOnInit() {<br>      this.user$ = this.userService.getUser();<br>    }<br>  }</pre><p>In the snippet above, the UserDetailComponent collects user data from the UserService and communicates this information to its template. This use of components simplifies and encapsulates the data collection and display process, so the component doesn&#39;t concern itself with where the data came from or where it&#39;s going.</p><h4>Establishing The Component State</h4><p>In addition to collecting and displaying data, components have another potential concern: managing their state. The ‘state’ in this context encompasses the various conditions a component can exist within throughout the lifetime of an app. Understanding and handling the different states of a component is pivotal for efficiently maintaining the component’s behavior and data flow.</p><p>The state of a component could be:</p><ol><li>It’s retrieving data (isLoading state).</li><li>It’s submitting data (isSubmitting state).</li><li>The component has data (hasData state).</li><li>The component is in an error state due to an unsuccessful API call (isError state).</li></ol><p>A design strategy where each state of a component is clear-cut and well-defined makes it easier to handle the rendering of each state, keeping robust and dynamic user interfaces even with unpredictable data outcomes.</p><h4>UI Services: Mediating Data Operations</h4><p>Cutting through the complexity that arises with handling data operations and state management of an Angular component, UI Services can make for an eloquent solution.</p><p>UI Services, as the name suggests, act as a mediator or broker for data operations between components and domain services, which implement business logic. They leverage the Dependency Injection (DI) system in Angular to share data across components which gives more control over the components’ state and reduces their concerns.</p><p>UI Services are beneficial as they ensure that:</p><ol><li>Components remain ‘thin’, focusing only on their primary concern — collecting or displaying data.</li><li>Data is persisted across routes, ensuring a more smooth user experience.</li><li>Duplication of data fetching logic is minimized.</li></ol><pre>@Injectable()<br>export class UserUIStateService {<br>  private isLoading$ = new BehaviorSubject&lt;boolean&gt;(false);<br>  private isError$ = new BehaviorSubject&lt;boolean&gt;(false);<br><br>  constructor(private userService: UserService) {}<br><br>  loadUser() {<br>    this.isLoading$.next(true);<br>    this.userService.getUser()<br>      .pipe(finalize(() =&gt; this.isLoading$.next(false)))<br>      .subscribe(() =&gt; {}, () =&gt; this.isError$.next(true));<br>  }<br>  <br>  getUserDataState(): Observable&lt;DataState&gt; {<br>    return combineLatest([this.isLoading$, this.isError$])<br>      .pipe(map(([isLoading, isError]) =&gt; ({ isLoading, isError })));<br>  }<br>}</pre><p>In the code sample above, the UserUIStateService is a UI Service. It&#39;s mediating between the userService (a domain service) and an Angular component to manage the user data. It uses BehaviorSubjects to manage and expose the state of the component (whether it&#39;s loading or error), and the loadUser method controls fetching data from the UserService while updating the loading and error state.</p><h4>Conclusion</h4><p>By taking the time to properly determine the concerns and responsibilities of the components in your Angular applications, you’ll be better equipped to design and build applications that are scalable, robust, and easy to maintain.</p><p>The use of UI Services significantly reduces complexity, enhances code readability, and simplifies data and state management within components. By successfully delegating responsibilities between the layers of an application, developers can navigate through large codebases more efficiently and troubleshoot more effectively.</p><p>As with all architectural decisions, the use of layered architecture and components requires careful planning and consideration, but the benefits are compelling — a more organized, maintainable, and scalable enterprise web application. Dedicate some time to understand and implement such practices, and you’ll undoubtedly see the merits and benefits reflected in your Angular applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c3c457212ea4" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/angular-components-in-enterprise-web-applications-managing-and-simplifying-their-concerns-with-ui-c3c457212ea4">Angular Components in Enterprise Web Applications: Managing and Simplifying their concerns with UI…</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Increasing Security and Improving Efficiency in Enterprise Applications with Angular Directives]]></title>
            <link>https://medium.com/angularlicious/increasing-security-and-improving-efficiency-in-enterprise-applications-with-angular-directives-ae0e6a64926a?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/ae0e6a64926a</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Fri, 25 Aug 2023 22:24:44 GMT</pubDate>
            <atom:updated>2023-08-25T22:24:44.911Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h4>Locks on the door are no good if you do not use them.</h4><p>Software developers and architects know that enterprise applications need a blend of the perfect blend of functionality, efficiency, and security. The ideal code would improve the user’s experience while ensuring the application’s stability. Within Angular, a TypeScript-based framework, we have a secret weapon to achieve this: Directives!</p><p>This blog post focuses on creating two directives — a sanitizer for preventing SQL Injection and Cross-Site Scripting (XSS) attacks and a trimmer to maintain the cleanliness of your input data.</p><p>Angular provides built-in functionality for creating directives to extend the functionality of HTML attributes and tags. A critical tool within Angular for working with Directives is the NG_VALUE_ACCESSOR, which provides a bridge between Angular&#39;s forms API and its DOM elements.</p><p>We will start with the code to develop the directives, and then I will provide detailed explanations.</p><h4>Sanitizer Directive</h4><pre>// sanitize.directive.ts<br>import {Directive, forwardRef, HostListener} from &#39;@angular/core&#39;;<br>import {NG_VALUE_ACCESSOR, ControlValueAccessor} from &#39;@angular/forms&#39;;<br><br>@Directive({<br>  selector: &#39;[appSanitizeValues]&#39;,<br>  providers: [<br>    {<br>      provide: NG_VALUE_ACCESSOR,<br>      useExisting: forwardRef(() =&gt; SanitizeDirective),<br>      multi: true<br>    }<br>  ]<br>})<br>export class SanitizeDirective implements ControlValueAccessor {<br>  // To hold the sanitized value<br>  sanitizedValue: any = &#39;&#39;;<br>  onTouched: any;<br>  onChange: any;<br><br>  // Listen to input changes<br>  @HostListener(&#39;input&#39;, [&#39;$event.target.value&#39;])<br>  inputChanged(value: string) {<br>    const el = document.createElement(&#39;div&#39;);<br>    el.innerHTML = value; // converts the value to HTML to be sanitized<br>    this.sanitizedValue = el.textContent || el.innerText; // gets the sanitized value<br>    this.onChange(this.sanitizedValue); // emits the sanitized value to the Form API<br>  }<br><br>  registerOnChange(fn: any): void {<br>    this.onChange = fn;<br>  }<br><br>  registerOnTouched(fn: any): void {<br>    this.onTouched = fn;<br>  }<br><br>  writeValue(value: any): void {<br>    this.sanitizedValue = value || &#39;&#39;;<br>  }<br>}</pre><h4>Trimmer Directive</h4><pre>// trim.directive.ts<br>import {Directive, forwardRef, HostListener} from &#39;@angular/core&#39;;<br>import {NG_VALUE_ACCESSOR, ControlValueAccessor} from &#39;@angular/forms&#39;;<br><br>@Directive({<br>  selector: &#39;[appTrimValues]&#39;,<br>  providers: [<br>    {<br>      provide: NG_VALUE_ACCESSOR,<br>      useExisting: forwardRef(() =&gt; TrimDirective),<br>      multi: true<br>    }<br>  ]<br>})<br>export class TrimDirective implements ControlValueAccessor {<br>  // To hold the trimmed value<br>  trimmedValue: any = &#39;&#39;;<br>  onTouched: any;<br>  onChange: any;<br><br>  // Listen to input changes<br>  @HostListener(&#39;input&#39;, [&#39;$event.target.value&#39;])<br>  input(value: string): void {<br>    this.trimmedValue = value.trim(); // Trims the value<br>    this.onChange(this.trimmedValue); // Emits the trimmed value to the Form API<br>  }<br><br>  registerOnChange(fn: any): void {<br>    this.onChange = fn;<br>  }<br><br>  registerOnTouched(fn: any): void {<br>    this.onTouched = fn;<br>  }<br><br>  writeValue(value: any): void {<br>    this.trimmedValue = value || &#39;&#39;;<br>  }<br>}</pre><p>Now that we have created both directives let’s dive into the details of how they work.</p><h4>Understanding NG_VALUE_ACCESSOR and ControlValueAccessor</h4><p>The NG_VALUE_ACCESSOR is a token used by Angular&#39;s Form API to access the native elements. It is combined with ControlValueAccessor, an interface that acts as a bridge between Angular&#39;s Form API and native DOM elements. By using the ControlValueAccessor interface, we can customize the way values are passed from the DOM to the Form API and vice versa.</p><p>Each directive contains a registerOnChange function that Angular calls to update the form model when the model changes. It also has a registerOnTouched function, which gets called when the form control is touched.</p><p>writeValue is used to write a new value from the form model into the view or (if needed) DOM property.</p><h4>Understanding the Directive Code</h4><p>The @Directive decorator creates a new directive definition process, and inside it, we are passing in some metadata.</p><ul><li>selector : &#39;[appSanitizeValues]&#39; or &#39;[appTrimValues]&#39; - These selectors tell Angular how to find the directive usage in the HTML template.</li><li>providers - This tells Angular how to provide the NG_VALUE_ACCESSOR.</li><li>provide: NG_VALUE_ACCESSOR - This is what the provider supplies.</li><li>useExisting - tells Angular that the provider is going to use an existing token</li><li>forwardRef - We need forwardRef here because SanitizeDirective and TrimDirective aren&#39;t defined until later, yet we are referencing it inside of itself.</li><li>multi: true - This allows for multiple directives to be applied to the same host element.</li></ul><p>One thing you will notice is that both directives are strikingly similar. That’s because, in Angular, the ControlValueAccessor will always have this structure.</p><p>Finally, in your main Angular module or a shared module, add your directives to the declarations array to be recognized by Angular&#39;s compiler and available for use throughout the application.</p><pre>import {SanitizeDirective} from &#39;./sanitize.directive&#39;;<br>import {TrimDirective} from &#39;./trim.directive&#39;;<br><br>@NgModule({<br>  declarations: [<br>    SanitizeDirective,<br>    TrimDirective<br>  ],<br>})</pre><h3>Conclusion</h3><p>Directives offer a powerful way to encapsulate and share behaviour changes in our Angular applications. For an enterprise-level application, using directives can help standardize functionality across vast codebases, keeping everything clean and consistent! By using NG_VALUE_ACCESSOR and ControlValueAccessor, we can leverage Angular&#39;s powerful Forms API to extend our application&#39;s functionality and enhance our control of user-generated input.</p><p>By creating a sanitizer directive, we provide an elegant solution to prevent harmful injections, increasing the overall security of our application. The trimmer directive maintains clean data in our forms for a seamless user experience. Making these part of the application initialization allows us to avoid repetitive code and unnecessary overhead.</p><p>With these new tools in your arsenal, your Angular enterprise application is poised to operate securely and effectively. Remember that the best code is not only efficient but also clean and easy to understand. Happy Coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ae0e6a64926a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/increasing-security-and-improving-efficiency-in-enterprise-applications-with-angular-directives-ae0e6a64926a">Increasing Security and Improving Efficiency in Enterprise Applications with Angular Directives</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular Components in Enterprise Web Applications: Managing and Simplifying their concerns with UI…]]></title>
            <link>https://medium.com/angularlicious/angular-components-in-enterprise-web-applications-managing-and-simplifying-their-concerns-with-ui-2e985f1cf4fa?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e985f1cf4fa</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Fri, 25 Aug 2023 04:17:45 GMT</pubDate>
            <atom:updated>2023-08-25T04:17:45.226Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h3>Angular Components in Enterprise Web Applications: Managing and Simplifying their concerns with UI Services</h3><h4>Complex applications require more simplicity.</h4><p>In the world of Angular development, components are often considered the bedrock upon which apps are built. Couple this with a layered architecture where you separate the concerns of an application, understanding the responsibilities of an Angular component becomes even more crucial.</p><p>This article aims to address the concern of Angular Components within Enterprise web applications, how to manage and simplify these concerns and, in particular, why the use of UI Services can help mediate these responsibilities, ensuring robust, scalable, and maintainable enterprise-level applications.</p><h4>What Is The Concern Of An Angular Component?</h4><p>Before delving into the specifics of managing an Angular component’s concerns, we must first define what we mean by a ‘concern’. In the context of system design, a ‘concern’ is a particular aspect of the system’s functionality. For an Angular Component, the main concern lies in collecting or displaying information.</p><p>Components are one of the fundamental building blocks of any Angular application, and they serve as a conduit between the template (HTML) and the underlying data (services). In other words, components are responsible for rendering data and handling user interaction. They form the user interface logic which serve distinct purposes within the user interface, and consequently, they should only be concerned with their specific role in this domain.</p><pre>@Component({<br>    selector: &#39;app-user-detail&#39;,<br>    templateUrl: &#39;user-detail.component.html&#39;<br>  })<br>  export class UserDetailComponent {<br>    user$: Observable&lt;User&gt;;<br><br>    constructor(private userService: UserService) {}<br><br>    ngOnInit() {<br>      this.user$ = this.userService.getUser();<br>    }<br>  }</pre><p>In the snippet above, the UserDetailComponent collects user data from the UserService and communicates this information to its template. This use of components simplifies and encapsulates the data collection and display process, so the component doesn&#39;t concern itself with where the data came from or where it&#39;s going.</p><h4>Establishing The Component State</h4><p>In addition to collecting and displaying data, components have another potential concern: managing their state. The ‘state’ in this context encompasses the various conditions a component can exist within throughout the lifetime of an app. Understanding and handling the different states of a component is pivotal for efficiently maintaining the component’s behavior and data flow.</p><p>The state of a component could be:</p><ol><li>It’s retrieving data (isLoading state).</li><li>It’s submitting data (isSubmitting state).</li><li>The component has data (hasData state).</li><li>The component is in an error state due to an unsuccessful API call (isError state).</li></ol><p>A design strategy where each state of a component is clear-cut and well-defined makes it easier to handle the rendering of each state, keeping robust and dynamic user interfaces even with unpredictable data outcomes.</p><h4>UI Services: Mediating Data Operations</h4><p>Cutting through the complexity that arises with handling data operations and state management of an Angular component, UI Services can make for an eloquent solution.</p><p>UI Services, as the name suggests, act as a mediator or broker for data operations between components and domain services, which implement business logic. They leverage the Dependency Injection (DI) system in Angular to share data across components which gives more control over the components’ state and reduces their concerns.</p><p>UI Services are beneficial as they ensure that:</p><ol><li>Components remain ‘thin’, focusing only on their primary concern — collecting or displaying data.</li><li>Data is persisted across routes, ensuring a more smooth user experience.</li><li>Duplication of data fetching logic is minimized.</li></ol><pre>@Injectable()<br>export class UserUIStateService {<br>  private isLoading$ = new BehaviorSubject&lt;boolean&gt;(false);<br>  private isError$ = new BehaviorSubject&lt;boolean&gt;(false);<br><br>  constructor(private userService: UserService) {}<br><br>  loadUser() {<br>    this.isLoading$.next(true);<br>    this.userService.getUser()<br>      .pipe(finalize(() =&gt; this.isLoading$.next(false)))<br>      .subscribe(() =&gt; {}, () =&gt; this.isError$.next(true));<br>  }<br>  <br>  getUserDataState(): Observable&lt;DataState&gt; {<br>    return combineLatest([this.isLoading$, this.isError$])<br>      .pipe(map(([isLoading, isError]) =&gt; ({ isLoading, isError })));<br>  }<br>}</pre><p>In the code sample above, the UserUIStateService is a UI Service. It&#39;s mediating between the userService (a domain service) and an Angular component to manage the user data. It uses BehaviorSubjects to manage and expose the state of the component (whether it&#39;s loading or error), and the loadUser method controls fetching data from the UserService while updating the loading and error state.</p><h4>Conclusion</h4><p>By taking the time to properly determine the concerns and responsibilities of the components in your Angular applications, you’ll be better equipped to design and build applications that are scalable, robust, and easy to maintain.</p><p>The use of UI Services significantly reduces complexity, enhances code readability, and simplifies data and state management within components. By successfully delegating responsibilities between the layers of an application, developers can navigate through large codebases more efficiently and troubleshoot more effectively.</p><p>As with all architectural decisions, the use of layered architecture and components requires careful planning and consideration, but the benefits are compelling — a more organized, maintainable, and scalable enterprise web application. Dedicate some time to understand and implement such practices, and you’ll undoubtedly see the merits and benefits reflected in your Angular applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2e985f1cf4fa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/angular-components-in-enterprise-web-applications-managing-and-simplifying-their-concerns-with-ui-2e985f1cf4fa">Angular Components in Enterprise Web Applications: Managing and Simplifying their concerns with UI…</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Increasing Security and Improving Efficiency in Enterprise Applications with Angular Directives]]></title>
            <link>https://medium.com/angularlicious/increasing-security-and-improving-efficiency-in-enterprise-applications-with-angular-directives-3fe7929e43a3?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/3fe7929e43a3</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Fri, 25 Aug 2023 00:33:41 GMT</pubDate>
            <atom:updated>2023-08-25T00:33:41.474Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h4>Locks on the door are no good if you do not use them.</h4><p>Software developers and architects know that enterprise applications need a blend of the perfect blend of functionality, efficiency, and security. The ideal code would improve the user’s experience while ensuring the application’s stability. Within Angular, a TypeScript-based framework, we have a secret weapon to achieve this: Directives!</p><p>This blog post focuses on creating two directives — a sanitizer for preventing SQL Injection and Cross-Site Scripting (XSS) attacks and a trimmer to maintain the cleanliness of your input data.</p><p>Angular provides built-in functionality for creating directives to extend the functionality of HTML attributes and tags. A critical tool within Angular for working with Directives is the NG_VALUE_ACCESSOR, which provides a bridge between Angular&#39;s forms API and its DOM elements.</p><p>We will start with the code to develop the directives, and then I will provide detailed explanations.</p><h4>Sanitizer Directive</h4><pre>// sanitize.directive.ts<br>import {Directive, forwardRef, HostListener} from &#39;@angular/core&#39;;<br>import {NG_VALUE_ACCESSOR, ControlValueAccessor} from &#39;@angular/forms&#39;;<br><br>@Directive({<br>  selector: &#39;[appSanitizeValues]&#39;,<br>  providers: [<br>    {<br>      provide: NG_VALUE_ACCESSOR,<br>      useExisting: forwardRef(() =&gt; SanitizeDirective),<br>      multi: true<br>    }<br>  ]<br>})<br>export class SanitizeDirective implements ControlValueAccessor {<br>  // To hold the sanitized value<br>  sanitizedValue: any = &#39;&#39;;<br>  onTouched: any;<br>  onChange: any;<br><br>  // Listen to input changes<br>  @HostListener(&#39;input&#39;, [&#39;$event.target.value&#39;])<br>  inputChanged(value: string) {<br>    const el = document.createElement(&#39;div&#39;);<br>    el.innerHTML = value; // converts the value to HTML to be sanitized<br>    this.sanitizedValue = el.textContent || el.innerText; // gets the sanitized value<br>    this.onChange(this.sanitizedValue); // emits the sanitized value to the Form API<br>  }<br><br>  registerOnChange(fn: any): void {<br>    this.onChange = fn;<br>  }<br><br>  registerOnTouched(fn: any): void {<br>    this.onTouched = fn;<br>  }<br><br>  writeValue(value: any): void {<br>    this.sanitizedValue = value || &#39;&#39;;<br>  }<br>}</pre><h4>Trimmer Directive</h4><pre>// trim.directive.ts<br>import {Directive, forwardRef, HostListener} from &#39;@angular/core&#39;;<br>import {NG_VALUE_ACCESSOR, ControlValueAccessor} from &#39;@angular/forms&#39;;<br><br>@Directive({<br>  selector: &#39;[appTrimValues]&#39;,<br>  providers: [<br>    {<br>      provide: NG_VALUE_ACCESSOR,<br>      useExisting: forwardRef(() =&gt; TrimDirective),<br>      multi: true<br>    }<br>  ]<br>})<br>export class TrimDirective implements ControlValueAccessor {<br>  // To hold the trimmed value<br>  trimmedValue: any = &#39;&#39;;<br>  onTouched: any;<br>  onChange: any;<br><br>  // Listen to input changes<br>  @HostListener(&#39;input&#39;, [&#39;$event.target.value&#39;])<br>  input(value: string): void {<br>    this.trimmedValue = value.trim(); // Trims the value<br>    this.onChange(this.trimmedValue); // Emits the trimmed value to the Form API<br>  }<br><br>  registerOnChange(fn: any): void {<br>    this.onChange = fn;<br>  }<br><br>  registerOnTouched(fn: any): void {<br>    this.onTouched = fn;<br>  }<br><br>  writeValue(value: any): void {<br>    this.trimmedValue = value || &#39;&#39;;<br>  }<br>}</pre><p>Now that we have created both directives let’s dive into the details of how they work.</p><h4>Understanding NG_VALUE_ACCESSOR and ControlValueAccessor</h4><p>The NG_VALUE_ACCESSOR is a token used by Angular&#39;s Form API to access the native elements. It is combined with ControlValueAccessor, an interface that acts as a bridge between Angular&#39;s Form API and native DOM elements. By using the ControlValueAccessor interface, we can customize the way values are passed from the DOM to the Form API and vice versa.</p><p>Each directive contains a registerOnChange function that Angular calls to update the form model when the model changes. It also has a registerOnTouched function, which gets called when the form control is touched.</p><p>writeValue is used to write a new value from the form model into the view or (if needed) DOM property.</p><h4>Understanding the Directive Code</h4><p>The @Directive decorator creates a new directive definition process, and inside it, we are passing in some metadata.</p><ul><li>selector : &#39;[appSanitizeValues]&#39; or &#39;[appTrimValues]&#39; - These selectors tell Angular how to find the directive usage in the HTML template.</li><li>providers - This tells Angular how to provide the NG_VALUE_ACCESSOR.</li><li>provide: NG_VALUE_ACCESSOR - This is what the provider supplies.</li><li>useExisting - tells Angular that the provider is going to use an existing token</li><li>forwardRef - We need forwardRef here because SanitizeDirective and TrimDirective aren&#39;t defined until later, yet we are referencing it inside of itself.</li><li>multi: true - This allows for multiple directives to be applied to the same host element.</li></ul><p>One thing you will notice is that both directives are strikingly similar. That’s because, in Angular, the ControlValueAccessor will always have this structure.</p><p>Finally, in your main Angular module or a shared module, add your directives to the declarations array to be recognized by Angular&#39;s compiler and available for use throughout the application.</p><pre>import {SanitizeDirective} from &#39;./sanitize.directive&#39;;<br>import {TrimDirective} from &#39;./trim.directive&#39;;<br><br>@NgModule({<br>  declarations: [<br>    SanitizeDirective,<br>    TrimDirective<br>  ],<br>})</pre><h3>Conclusion</h3><p>Directives offer a powerful way to encapsulate and share behaviour changes in our Angular applications. For an enterprise-level application, using directives can help standardize functionality across vast codebases, keeping everything clean and consistent! By using NG_VALUE_ACCESSOR and ControlValueAccessor, we can leverage Angular&#39;s powerful Forms API to extend our application&#39;s functionality and enhance our control of user-generated input.</p><p>By creating a sanitizer directive, we provide an elegant solution to prevent harmful injections, increasing the overall security of our application. The trimmer directive maintains clean data in our forms for a seamless user experience. Making these part of the application initialization allows us to avoid repetitive code and unnecessary overhead.</p><p>With these new tools in your arsenal, your Angular enterprise application is poised to operate securely and effectively. Remember that the best code is not only efficient but also clean and easy to understand. Happy Coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3fe7929e43a3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/increasing-security-and-improving-efficiency-in-enterprise-applications-with-angular-directives-3fe7929e43a3">Increasing Security and Improving Efficiency in Enterprise Applications with Angular Directives</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building Dynamic UIs: Angular’s Component-Based Approach Meets Enterprise Patterns]]></title>
            <link>https://medium.com/angularlicious/building-dynamic-uis-angulars-component-based-approach-meets-enterprise-patterns-32843072a8fc?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/32843072a8fc</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Thu, 24 Aug 2023 22:47:01 GMT</pubDate>
            <atom:updated>2023-08-24T22:47:01.779Z</atom:updated>
            <cc:license>https://creativecommons.org/publicdomain/mark/1.0/</cc:license>
            <content:encoded><![CDATA[<h4>Enterprise solutions have different problems and require different solutions.</h4><h3>Building Dynamic UIs: Angular’s Component-Based Approach Meets Enterprise Patterns</h3><p>Developing dynamic and responsive user interfaces present a unique challenge in the realm of enterprise applications. They must be scalable, maintainable, and able to handle large volumes of data while providing an intuitive and responsive user experience.</p><p>Angular, a robust front-end web application framework by Google, provides a solid solution to this challenge. Offering a component-based architecture, Angular encourages developers to break their application into smaller, reusable pieces called components. This approach greatly simplifies the process of creating complex user interfaces and promotes modularity, reusability, and testability.</p><p>This blog post will demystify the complexities of building dynamic user interfaces in enterprise applications. We will delve into the nuances of Angular’s component-based architecture and see how it aligns with CLEAN architecture and SOLID principles. Additionally, it will demonstrate this with practical, enterprise-level code examples and best practices to help the learner grasp these concepts effectively.</p><h3>Challenges in Building Complex and Dynamic UIs</h3><p>Developing user interfaces for enterprise applications is fraught with challenges that stem from their inherent complexity and the dynamic nature of business processes. These UIs need to be adaptable, scalable, and able to cater to a variety of user roles and workflows.</p><p>Further, enterprise applications generally integrate with several other systems and services. Therefore, the UI has to provide a seamless interface that abstracts this complexity from the user. Implementing such UIs that stay resilient against these challenges requires a well-defined architecture and appropriate design patterns.</p><h3>Angular’s Component-Based Architecture</h3><p>Angular addresses these challenges with its hierarchical component-based architecture. As per this architecture, an Angular application is basically a tree of components. Each component is an independent, self-contained piece of UI that encapsulates its own state (data), view (template), and logic (class).</p><p>Component-based architecture has a number of benefits. It:</p><ul><li>Promotes <strong>modularity</strong> and <strong>reusability</strong>, as components are independent and can be reused across different parts of the application.</li><li>Simplifies <strong>unit testing</strong>, as components can be tested independently.</li><li>Enhances <strong>maintainability</strong> and <strong>readability</strong>, as each component focuses on a single responsibility.</li><li>Facilitates <strong>parallel development</strong>, wherein different teams can work on different components simultaneously, without stepping on each others’ toes.</li></ul><p>Let’s illustrate this with a code example. Suppose you are building an e-commerce application. You could have individual components for Header, Footer, Product List, Shopping Cart, and so on. The ‘Product List’ component might look something like this:</p><pre>import { Component, OnInit } from &#39;@angular/core&#39;;<br>import { Product } from &#39;../models/product&#39;;<br>import { ProductService } from &#39;../services/product.service&#39;;<br><br>@Component({<br>  selector: &#39;app-product-list&#39;,<br>  templateUrl: &#39;./product-list.component.html&#39;,<br>  styleUrls: [&#39;./product-list.component.css&#39;]<br>})<br>export class ProductListComponent implements OnInit {<br>  products: Product[];<br>  <br>  constructor(private productService: ProductService) { }<br>  <br>  ngOnInit(): void {<br>    this.products = this.productService.getProducts();<br>  }<br>}</pre><p>The ProductListComponent is a self-contained unit of the application that is responsible for fetching and displaying the list of products. It uses ProductService to fetch the products, which could be coming from a back-end API. The component doesn&#39;t need to know where the data is coming from. It simply focuses on rendering the data it gets in the best way possible.</p><h3>Integration with Enterprise Patterns</h3><p>The component-based architecture of Angular aligns well with key software engineering principles, such as SOLID principles and CLEAN architecture. These principles guide developers to build scalable, maintainable, and testable software.</p><p>For instance, the ‘Single Responsibility Principle’ of SOLID encourages developers to have each class (component, in Angular’s case) responsible for a single piece of functionality. The above example of ProductListComponent is a great demonstration of the SRP principle. The component has one and only one responsibility: to manage and display a list of products.</p><p>The Dependency Inversion Principle is another example, which states that high-level modules shouldn’t depend directly on low-level modules. Rather, they should depend on abstractions. The ProductListComponent in our example depends on ProductService, an abstraction of the data fetching logic, rather than depend directly on a database or an API.</p><p>A quick note on Nx Workspace: a powerful monorepo tool by Nrwl. It goes hand in hand with Angular (and other similar technologies) by providing efficient tools for code management and scalability. The use of Nx Workspace is beyond the scope of this blog post, but it’s highly recommended for managing code in large, enterprise-level Angular applications.</p><h3>Best Practices for Clean Architecture</h3><p>Imbuing your Angular project with the principles of clean architecture goes a long way in ensuring its scalability, maintainability, and testability. Here are some best practices to follow:</p><ol><li><strong>Adhere to the Single Responsibility Principle (SRP).</strong> Each component, service, or class should do one thing and do it well.</li><li><strong>Leverage Angular’s Dependency Injection.</strong> Use services to handle cross-component communication and external service interaction. Services in Angular are singleton objects that get instantiated only once during the lifetime of an application.</li><li><strong>Enforce strict separation of concerns.</strong> Segregate the application functionality using modules. For example, Authentication, User Management, and Products could be different modules in an e-commerce application.</li><li><strong>Use Angular Routing for navigational concerns.</strong> Angular offers a powerful router module that helps in managing navigation and maintaining the state of the application.</li><li><strong>Test your components and services.</strong> Angular offers robust testing tools out of the box. Leveraging these to create unit and integration tests is a great way to enforce the correctness of your codebase.</li></ol><h3>Conclusion</h3><p>Creating dynamic, scalable, and maintainable user interfaces for enterprise applications can be a daunting task. However, Angular’s component-based architecture, along with adherence to SOLID principles and Clean Architecture patterns, can help simplify the process.</p><p>With a mélange of modern design principles, best practices, and a concise codebase, this blog post has strived to demonstrate how complexity in UI development can be mitigated significantly. Further, it highlighted how embracing principled design patterns and Angular’s superb tooling can lead to a more streamlined, efficient, and satisfying developer experience.</p><p>Creative, component-based design fosters a clean, intelligent strategy towards web application development. It empowers teams to build streamlined applications that are easy to navigate, maintain, and expand. So, embrace these powerful techniques and unleash the full potential of your Angular applications! Armed with these strategies, you are well on your way to mastering complex UI development in enterprise environments.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=32843072a8fc" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/building-dynamic-uis-angulars-component-based-approach-meets-enterprise-patterns-32843072a8fc">Building Dynamic UIs: Angular’s Component-Based Approach Meets Enterprise Patterns</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Angular Business Rules & Validation Strategies]]></title>
            <link>https://angularlicious.medium.com/angular-business-rules-validation-strategies-8c3c8c9069e0?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8c3c8c9069e0</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[rule-engine]]></category>
            <category><![CDATA[angular-architecture]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[matt-vaughn]]></category>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Sun, 29 Aug 2021 14:46:39 GMT</pubDate>
            <atom:updated>2021-08-29T14:46:39.766Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="Angular Business Rules and Validation Strategies" src="https://cdn-images-1.medium.com/max/1024/1*z_IwpDnrF5SgcPL-2d558A.png" /></figure><p>Today, most web applications are not simple — especially when they include forms, APIs, and a database. Modern web applications now contain complex business rules and data validation requirements. Most business applications collect a fair amount of data. This means that the application or software must verify or validate that the information is correct before making expensive API calls. In addition to this, there may be other business rules that must be evaluated to ensure that the business logic is correct.</p><p>Therefore, what is your strategy to implement business rules and data validation? Most likely if you have five developers on your development team you will have five different ways to manage business rules and data validation. Over a period of time, the variance in the implementation of this type of code will create technical debt that will be difficult to overcome. If the application supports revenue generation then it is essential that the code is conventional, consistent, repeatable, and for sure testable.</p><h3>Game Plan and Strategy</h3><blockquote>Hope is not a good strategy. If you hope the code will just work and the business rules will be fine without any thought or planning, good luck!</blockquote><p>There are different sources in your application that may require validation. The validation and business rule strategy may include the Angular form validators. However, this is just the first layer of validation and business rule processing of the application. As the code progresses towards making an API call there are other opportunities for validation and business rule processing. Most likely there will be different types of validation using different mechanisms.</p><p>I like to imagine a set of safety nets that are layered depending on the layer of the application (UI/UX, UI Services, domain service layers, business logic, and data access/HTTP calls). This is where it gets interesting. In the lower layers of your application, you cannot use the reactive form Validators that implements the ValidatorFn <em>interface</em>. Therefore you might want to consider using a rule engine to create a more conventional way to manage validation and business rules.</p><h3>Type of Validation and Rules</h3><ol><li>form input (synchronous)</li><li>asynchronous validation of form input that may include an API operation</li><li>business logic with business rules</li><li>data validation before an API call</li></ol><p>Occasionally you might need to create a custom validator for form input. This custom validator might be synchronous or async. Either way, you will need to write some custom code. The validator must also be testable to verify the results. It should be a <a href="https://betterprogramming.pub/what-is-a-pure-function-3b4af9352f6f">pure function</a> — see an example <a href="https://gist.github.com/wesleygrimes/f5bdf06c5c85fd3c8cb849111b5b3de2">here</a>.</p><h3>Motivation</h3><p>Two core principles of great software design are <a href="https://en.wikipedia.org/wiki/Separation_of_concerns">Separation of Concerns (SoC)</a> and <a href="https://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility</a>. Business rules and validation are an integral part of most business applications. There are rules and validations that must occur during the processing of business logic. Most applications will combine the business logic with rules and data validation — when this happens, testing and maintaining applications becomes more difficult.</p><p>A rule engine allows the application to have a good Separation of Concerns (SOR). A good rule engine allows you to:</p><ul><li>Quickly start using out-of-the-box rules that are already implemented.</li><li>Create custom rules that are either simple or composite.</li><li>Create rules that can be reused throughout the application. Code reuse eliminates copy/paste of common rules.</li><li>Use a single ValidationContext to add rules, execute rules, and evaluate the rule results.</li><li>Use a consistent pattern and mechanism to implement your business rules and data validation.</li><li>Integrate rules with Reactive Form custom validators (async or sync).</li></ul><p>The following diagram shows a strongly-typed Typescript rule engine that allows applications to implement simple or sophisticated business rules as well as data validation. It contains a set of common rules ready for use; as well as a framework and set of classes to create custom rules for Angular applications, components, services, and library projects.</p><blockquote><em>Do not worry about the complexity of the diagram below. The diagram shows the internal design of the rule engine. The </em><em>ValidationContext provides a simple API to add rules, execute rules, and to retrieve rule results.</em></blockquote><figure><img alt="Rule Engine :: Composite Design Pattern Diagram" src="https://cdn-images-1.medium.com/max/1024/1*KUkJ_PUSs8sdxZYUOaxGNw.png" /></figure><p>The rule engine is using a simple design pattern called <a href="#resources">Composite</a>. This was the first library I created using TypeScript in 2016. This was a turning point for me. I was currently using AngularJS. However, the new version of Angular 2 was just released and I was interested in its capabilities. One of my concerns was that the new version of angular was using TypeScript. Imagine that was a real concern that I had. I was a little apprehensive about adding a new programming language to my current list.</p><p>My thought was that if I could create a reusable library using TypeScript then I would learn Angular 2 along with TypeScript but with a focus on creating reusable libraries for my enterprise web applications.</p><h3>International JavaScript Conference (New York 2021)</h3><p>Well, five years later I am still focused on reusable libraries and Angular 2 or rather just Angular. Next month I will present at the <a href="https://javascript-conference.com/angular/custom-angular-libraries/">International JavaScript Conference in New York (September 27–30, 2021) on the topic of Custom Angular Libraries</a>.</p><figure><a href="https://javascript-conference.com/angular/custom-angular-libraries/"><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*U9g5YeBp00KpKfvq3Mnf8w.png" /></a><figcaption>2021 International JavaScript Conference:: New York:: Matt Vaughn</figcaption></figure><h3>Why use a rule engine?</h3><p>Here are some reasons for using a rule engine. The biggest reason is below.</p><ul><li>Provides a consistent way to implement business and validation rules and provides a consistent mechanism to retrieve the results.</li></ul><p>Most rule engines will come with predefined rules out of the box. Good rule engines will also have an API/Framework to allow you to create or compose custom rules using existing and other rules. This kind of capability is a game-changer.</p><p>The rule engine I use has a set of predefined rules ready to go.</p><ul><li>AreEqual</li><li>AreNotEqual</li><li>GuidIsValid</li><li>IsFalse</li><li>IsTrue</li><li>IsNullOrUndefined</li><li>IsNotNullOrUndefined</li><li>Max</li><li>Min</li><li>Range</li><li>StringIsRegExMatch</li><li>StringIsNotNullEmptyRange</li><li>StringIsNullEmptyRange</li></ul><p>More motivation and reasons to use a rule engine:</p><ul><li>You can create a reusable library of custom rules and use them in one or more applications.</li><li>Combine default with one or more custom rules to create a CompositeRule - a rule that contains other rules (ruleset).</li><li>Each rule has a Priority property to execute rule sets in a specified sequence.</li><li>Take advantage of Typescript classes to quickly create simple or composite (nested) rules using the API that is part of the framework.</li><li>Use the ValidationContext to simply add, execute, and retrieve rule results.</li><li>Code faster using Fluent API style syntax — be more productive.</li><li>Using the CompositeRule base class, you can create a rule that contains other rules of either simple or composite types. The rule execution algorithm manages the complexity - now you can create rules and reuse rules to match your business logic.</li></ul><h3>ValidationContext</h3><p>The ValidationContext is the container object for rules. It allows the developer to add, execute and retrieve the results of the evaluated rules.</p><ul><li>Add rules by calling the addRule() function.</li><li>Execute rules by calling the renderRules() function.</li><li>Retrieve the results (a list of RuleResult items) using the results public property.</li></ul><p>The following code snippet shows import statements and initialization of the ValidationContext as a member in the class.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a718f62c9d549a6e24a05403110f7b3b/href">https://medium.com/media/a718f62c9d549a6e24a05403110f7b3b/href</a></iframe><p>The following shows the entire ValidationContext class with its implementation details. It is straightforward, you make the calls in the following sequence:</p><ol><li>addRule(..): Add rules that you want to evaluate.</li><li>renderRules(): Renders all rules added to the ValidationContext.</li><li>Determine the state of the validation by using either: hasRuleViolations() or isValid(). Each returns a boolean value indicating the status of the validation context.</li><li>Retrieve the ValidationContext.results which is a array of RuleResult items.</li></ol><h3>ValidationContext</h3><p>The ValidationContext is the entry point into using the rule engine. It is small but powerful.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/273228b8b59f3dd598b02838d5b35238/href">https://medium.com/media/273228b8b59f3dd598b02838d5b35238/href</a></iframe><h3>Adding Rules to the ValidationContext</h3><p>Using an initialized [ValidationContext] object, you can add rules using a Fluent API syntax. The following example uses existing rules.</p><p>A rule requires:</p><ul><li><em>Name</em>: the name of the rule.</li><li><em>Message</em>: the text to display if the rule fails.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d5fa68744403f57b0315094952c8e2b4/href">https://medium.com/media/d5fa68744403f57b0315094952c8e2b4/href</a></iframe><p>Here is an example of a business action (unit of work) for adding a contact. It uses the ValidationContext to add a set of specific rules to validate the action. If all of the rules evaluate without any errors, the API is called with the contact DTO object.</p><blockquote><em>Focus on the </em><em>preValidateAction() method. This is where the rules are implemented for adding a new contact to the application.</em></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4d872257bb430cb40afbcfa36b8f0d53/href">https://medium.com/media/4d872257bb430cb40afbcfa36b8f0d53/href</a></iframe><h3>Custom Rules</h3><p>Notice that the rules for adding a new Contact contains an EmailAddressFormatIsValidRule rule.</p><blockquote><em>Custom rules inherit from either a </em><em>CompositeRule or a </em><em>SimpleRule. All rules inherit from the </em><em>RulePolicy class and are executed and evaluated the same way. A </em><a href="#ruleresult"><em>RuleResult</em></a><em> is returned when a simple or composite rule is evaluated.</em></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/36ea4803978c081835dcef4033b18719/href">https://medium.com/media/36ea4803978c081835dcef4033b18719/href</a></iframe><h3>Rules with Rules (Composite)</h3><blockquote><em>A </em>composite<em> rule is a collection of simple and composite rules.</em></blockquote><p>Notice that this composite rule contains another composite rule: StringIsRegExMatch. Rules can be an Object-Graph of rules - a rule chain. Where each rule or group of rules (Composite) must evaluate without any errors for the rule or context to be valid. If any rule fails within the ValidationContext the ValidationContextState.State is Failure.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3981d4669b78c7a9a1b548f773dfc332/href">https://medium.com/media/3981d4669b78c7a9a1b548f773dfc332/href</a></iframe><h3>Executing Rules</h3><p>When you have added one or more rules to an instance of a ValidationContext, you are ready to execute the rules. The renderRules() method will return the ValidationContext - each of the rules is evaluated against their specified targets. You are now ready to evaluate the rule results.</p><pre>this.validationContext.renderRules()</pre><h3>Evaluation Rule Results</h3><p>After the rules are executed, you can examine the rule results. Each rendered rule will have a result — either valid or not valid, based on the rule, criteria, and target value(s).</p><p>Many times it is useful to filter or extract the failed rules from the ValidationContext. The following code snippet shows how you would extract failed rules that are marked as displayable (i.e., e.rulePolicy.isDisplayable) into a list of ServiceMessage items.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/be4c76e20f6fcd8bbdc46537ad046423/href">https://medium.com/media/be4c76e20f6fcd8bbdc46537ad046423/href</a></iframe><h3>RulePolicy</h3><p>The RulePolicy is the base class for all rule types. The angular-rules-engine contains (2) types of rule implementations:</p><ol><li>Simple</li><li>Composite.</li></ol><p>These rule types form the basis of all rules in the rule engine. The rule engine uses the Composite Design Pattern — <a href="https://en.wikipedia.org/wiki/Composite_pattern">click here for more information about this pattern</a>. All rules have the following properties of information.</p><ul><li>isValid: Use to indicate the status of the rule after evaluation.</li><li>message: Use to provide a message for failed rules.</li><li>name: Use to create a name that identifies the specified rule.</li><li>priority: Use to assign a numeric value to the rule. Rules are sorted by priority and executed in the same sort sequence.</li><li>result: The output of an executed rule. It contains the result and RulePolicy information.</li><li>isDisplayable: Use to indicate if the rule result is displayable to the caller. Default value is false. You must explicitly provide a [true] value for this when initializing a new rule.</li><li>renderType: Currently the only option is RenderType.EvaluateAllRules.</li><li>severity: Use to indicate the severity (Exception, Warning, or Information) if the rule evaluation is not valid.</li><li>source: Use to indicate the source or location of the rule.</li></ul><p>The following RulePolicy class is the base class for all rules. Each of the default rules also extends either the SimpleRule or the CompositeRule. And each of these classes extends from the RulePolicy class. The allows <em>all</em> rules to have common behavior and execution strategies.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bea3b08ba8422961cdd3af4b40a60774/href">https://medium.com/media/bea3b08ba8422961cdd3af4b40a60774/href</a></iframe><h3>IRuleComponent</h3><p>This interface is just infrastructure for the rule engine. It provides the contract that all rules will contain an execute() method - this provides a consistent mechanism to begin the process of all rules that implement this interface.</p><pre>export interface IRuleComponent {<br>    execute(): RuleResult;<br>}</pre><h3>RuleResult</h3><p>The output of an executed rule is a RuleResult object that contains the rule (rulePolicy), an indicator for the rule&#39;s state (isValid), and a message to be used if the rule has failed.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4fadaa7c867878a0319f36e3984aa155/href">https://medium.com/media/4fadaa7c867878a0319f36e3984aa155/href</a></iframe><h3>Simple Rules</h3><p>The main difference between SimpleRule and a CompositeRule is how they are rendered during their execution. A simple rule has a single evaluation with a single result.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b8380ff603680bccd042d2af60469391/href">https://medium.com/media/b8380ff603680bccd042d2af60469391/href</a></iframe><p>The following code is the IsTrue rule. This rule evaluates the target and creates a new RuleResult in the render() method. Basically, the result is based on the evaluation of the target value. This render() method returns a single result. This is much different from a composite rule discussed later that has to return a RuleResult for each rule in a list of rules.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/bc4612cef935f0ba224d53cd179286a2/href">https://medium.com/media/bc4612cef935f0ba224d53cd179286a2/href</a></iframe><h3>Composite Rules</h3><p>A composite rule is a rule that contains a list of rules to be evaluated. A rule in this list can be a rule that extends from either SimpleRule or CompositeRule. This allows for a more complex implementation of rules - it is a very powerful pattern. You can have a rule that contains a list of rules, where one of those rules may be a CompositeRule, where one of those rules in the composite rule is a composite side-by-side with other simple and complex rules.</p><p>You are creating a rule tree where all rules will have to evaluate to be valid for the container rule to be valid. This pattern allows a developer to create new custom rules and then use those rules with the default rules to orchestrate a rule implementation against a target object or value.</p><p>The CompositeRule extends from RulePolicy which has the responsibility of calling render() on each rule. In the case of a composite rule, this method will iterate through the list of rules and call the execute() method of each rule. Then the results are processed to determine if <em>any</em> of the rules failed.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/be01752c0c569f28eb0ca2b827519f90/href">https://medium.com/media/be01752c0c569f28eb0ca2b827519f90/href</a></iframe><p>The following shows an implementation of a composite rule. Basically, this rule is using (2) default rules, both of which are also composite rules. All rules within each composite must evaluate to true for this rule to be valid.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ee2dc0f7d14470946324d0a9be97ba9/href">https://medium.com/media/8ee2dc0f7d14470946324d0a9be97ba9/href</a></iframe><p>The Range rule used in the composite rule above uses (2) simple rules to form the composite. Each rule has to evaluate to true for the entire rule to be valid.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a9595b9d4e4898af4448e08a8586a75a/href">https://medium.com/media/a9595b9d4e4898af4448e08a8586a75a/href</a></iframe><h3>Conclusion</h3><p>There are lots of details in the implementation of a rule engine. However, remember that you only need to initialize a ValidationContext, add rules, and then call the renderRules() to evaluate the ruleset and provide a list of RuleResult items. It is that simple. Happy rule rendering.</p><p>For more information on how this cross-cutting concern library is used within a CLEAN Architecture approach with SOLID principles — please visit <a href="https://www.angulararchitecture.com/">www.AngularArchitecture.com</a></p><h3>Resources</h3><ul><li><a href="https://dev.to/coly010/the-composite-pattern-design-patterns-meet-the-frontend-445e">The Composite Pattern — Design Patterns Meet the Frontend</a></li><li><a href="https://en.wikipedia.org/wiki/Composite_pattern">Composite Pattern (Wikipedia)</a></li><li><a href="https://www.dofactory.com/net/composite-design-pattern">Composite Pattern using C#</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8c3c8c9069e0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Keep Your Nx Workspace Clean with ESLint]]></title>
            <link>https://medium.com/angularlicious/keep-your-nx-workspace-clean-with-eslint-7dcb328910ac?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/7dcb328910ac</guid>
            <category><![CDATA[eslint]]></category>
            <category><![CDATA[angular-architecture]]></category>
            <category><![CDATA[angularlicious]]></category>
            <category><![CDATA[angular]]></category>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Sun, 23 May 2021 19:17:35 GMT</pubDate>
            <atom:updated>2021-06-16T03:06:09.858Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*_6xjFDzyiOVXyAK_bpLSSg.png" /><figcaption>Nx Workspace + ESLint = {CLEAN_CODE};</figcaption></figure><p>A new software project starts pristine — no code, no projects, no files. However, in just a few days or weeks of development there might be some variations of code syntax and formatting. This may be due to different developer styles, IDEs, text editors, tools, or even scaffolding generators.</p><p>It is much easier to gain control and manage the code syntax and formatting rules with a shared monorepo and Nx Workspace. A new Nx Workspace provides ESLint rules and configuration for all projects within a workspace.</p><h3>What Does It Do</h3><p>The name is the combination of ES and Lint. ESLint provides the ability to analyze (e.g., lint) your EcmaScript or TypeScript code to verify it meets the criteria of specified rules and required syntax. Typically, these tools are automated for the developer and also within a continuous integration (CI) environment.</p><ul><li>ES: EcmaScript</li><li>Lint: the name of a tool that analyzed C code in 1978</li></ul><p>Some advantages to using ESLint:</p><ul><li>Less errors in production</li><li>Readable, maintainable and more consistent code</li><li>Fewer discussions about code style and aesthetic choices during code reviews</li><li>Objective measurement of code quality</li></ul><h3>ESLint Configuration Cascades</h3><p>I like that our new Nx Workspace environment provides a <em>workspace-level</em> ESLint configuration using the .eslintrc.json file. You get this by default when you add/generate a project in the workspace.</p><ul><li>Create a new Nx Workspace: npx create-nx-workspace workspace --scope-name=angular-architecture</li><li>Add package to create an Angular application: yarn add @nrwl/angular@12.3.3 -D</li><li>Generate a fuzzy project that needs linting: nx g @nrwl/angular:application fuzzy</li></ul><p>When you add a new <em>project</em> to the Nx Workspace the CLI will add a new .eslintrc.json to the project. This means that the files in the project will use the closest .eslintrc.json configuration - if this configuration <em>extends</em> other configuration from upstream folders these rules will also be included in the lint evaluation process.</p><blockquote><em>Adding a </em><em>&quot;root&quot;: true to a lower-level configuration will stop the cascade effect of extended rules. This limits the rules to the specific level or project - nice, if you have a custom configuration for a specific use case.</em></blockquote><h3>Project Level ESLint</h3><p>Each project also contains a configuration for ESLint rules that apply to the <em>project-level</em> only using the overrides for the lint rules.</p><p>What is interesting about the project-level configuration is that it uses JSON extends to inherit lint settings from the workspace-level configuration using the extends list of .eslintrc.json files.</p><blockquote>There is a relationship between the project and the workspace level ESLint configuration files.</blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/cf28e591f1903d4686d433ea97f2ef5f/href">https://medium.com/media/cf28e591f1903d4686d433ea97f2ef5f/href</a></iframe><h3>Lint Your Angular Application</h3><p>Here is a simple example of a linting issue in our <em>fuzzy</em> application. Some developers or teams may not want the following issues in the code base.</p><ul><li>a console.log statement exists.</li><li>there is an empty ngOnInit method.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/826033cce0ab24cdcd79431bb7351bcd/href">https://medium.com/media/826033cce0ab24cdcd79431bb7351bcd/href</a></iframe><p>Run the CLI lint command to evaluate the code syntax using the rules in the current .eslintrc.json configuration for the project and workspace.</p><blockquote><em>run: </em><em>nx lint</em></blockquote><p>The output:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fbdc23d0cb6ecd4bcd8c8be5c364e134/href">https://medium.com/media/fbdc23d0cb6ecd4bcd8c8be5c364e134/href</a></iframe><p>Notice that the @angular-eslint/no-empty-lifecycle-method ESLint rule is an <em>error</em> for the empty method in the component file.</p><h3>ESLint on Save</h3><p>Add the following to your Visual Studio Code settings.json file.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b343d0c72f3f7f0a61f112ea91842402/href">https://medium.com/media/b343d0c72f3f7f0a61f112ea91842402/href</a></iframe><h3>Automated Formatting</h3><p>Linting and code formatting can work together. Note, linting is focused on syntax rules based ont the target language (e.g., TypeScript, HTML, etc.). While formatting is concerned with other things like using single or double quotes. Formatting is important because it is part of the <em>consistency</em> and <em>readability</em> factors of your code base.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1a68c29e1bf141cdd96932633cbe832e/href">https://medium.com/media/1a68c29e1bf141cdd96932633cbe832e/href</a></iframe><p>Configure Visual Studio Code to automatically format the entire file or modified code. Open your user settings and configure the Format section to save.</p><blockquote><em>There is more to integrate Prettier with ESLint </em><a href="https://nickymeuleman.netlify.app/blog/automagically-lint"><em>Integrate ESLint with Prettier</em></a><em>.</em></blockquote><h3>Where Are My Linting Rules</h3><p>Using Nx provides some really nice out-of-the-box configuration and setup for ESLint. There is a set of packages installed for the workspace that provide rules, plugins, and configuration for ESLint to <em>just work</em>. Here are the devDependencies that enable ESLint to work in the Nx Workspace.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2fb9f892367b92820ac2b3749d34dce1/href">https://medium.com/media/2fb9f892367b92820ac2b3749d34dce1/href</a></iframe><p>Below is an example of a lint error. It contains information that tells where the rule is coming from. The no-empty-lifecycle-method rule that was used to evaluate the component file is located in the @angular-eslint package.</p><blockquote><em>error Lifecycle methods should not be empty @angular-eslint/no-empty-lifecycle-method</em></blockquote><p>I really like that we can install a package that contains a set of ready to use rules. You can take the default settings and you can override any rules where you want to fine tune the configuration (i.e., off, warn, error).</p><h3>Conclusion</h3><p>The formatting and linting rules that you or your team use can be contextual to different factors. You can establish the rules, modify them over time — evaluate the impact on the team and the code quality. It is another tool that we have to create consistent code. The Nx Workspace makes it very easy to get started.</p><h3>Resources</h3><ul><li><a href="https://github.com/buildmotion/nx-eslint">Github.com: nx-eslint repository</a></li><li><a href="https://eslint.org/docs/user-guide/configuring/#extending-configuration-files">Configuring ESLint</a></li><li><a href="https://github.com/angular-eslint/angular-eslint#readme">Angular ESLint</a></li><li><a href="https://github.com/angular-eslint/angular-eslint#usage-with-nx-monorepos">Angular ESLint with Nx Workspace</a></li><li><a href="https://github.com/typescript-eslint/typescript-eslint">TypeScript ESLint</a></li><li><a href="https://www.testim.io/blog/what-is-a-linter-heres-a-definition-and-quick-start-guide/#:~:text=The%20term%20linter%20comes%20from,he%20worked%20at%20Bell%20Labs.">What Is a Linter? Here’s a Definition and Quick-Start Guide</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7dcb328910ac" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/keep-your-nx-workspace-clean-with-eslint-7dcb328910ac">Keep Your Nx Workspace Clean with ESLint</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Material Button with Icon + Stackblitz]]></title>
            <link>https://medium.com/angularlicious/material-button-with-icon-stackblitz-bb64e537d84c?source=rss-d1401157ae8c------2</link>
            <guid isPermaLink="false">https://medium.com/p/bb64e537d84c</guid>
            <category><![CDATA[angular]]></category>
            <category><![CDATA[angularlicious]]></category>
            <category><![CDATA[stackblitz]]></category>
            <category><![CDATA[material-design]]></category>
            <category><![CDATA[angular-architecture]]></category>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Tue, 24 Nov 2020 14:37:43 GMT</pubDate>
            <atom:updated>2020-11-24T14:37:43.655Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*46o7LiTMN5dSq7hwsx4ZgA.png" /></figure><p>I attended the Enterprise NG Conference by <a href="https://medium.com/u/f8f1fde1edbd">ng-conf</a> last week. Eric Simons (<a href="https://twitter.com/ericsimons40">@EricSimons40</a>) the founder of <a href="https://stackblitz.com/">StackBlitz</a> got me re-engaged with StackBlitz. I learned about StackBlitz 3 years ago when I attended an Angular Meetup hosted by StackBlitz in San Francisco (2017). I was on a pleasure trip with my wife — however, when I found out that the Angular Core Team was going to be there that evening I just had to go. It was a fun night!</p><p>One of the main use-cases of StackBlitz is for online documentation — to show some code, or rather a working application within a browser. This is an amazing feat. You can load an entire development environment within a few seconds and start writing code. Seeing this live 3 years ago was amazing.</p><p>It is easy to get a StackBlitz project embedded into a web page. I used the URL for my specific StackBlitz project and embedding it on my Medium blog. My URL:</p><pre><a href="https://stackblitz.com/edit/icon-button">https://stackblitz.com/edit/icon-button</a></pre><p>The result is a running Angular application with:</p><ul><li>Code Editor (Angular Project) with the latest version</li><li>Visual Studio Code experience in a browser</li><li>custom name for the StackBlitz project</li></ul><blockquote>You can click on the [Edit on StackBlitz] link and it will open the code and application in a separate window. You can also fork the project and modify the code.</blockquote><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fstackblitz.com%2Fedit%2Ficon-button%3Fembed%3D1&amp;display_name=StackBlitz&amp;url=https%3A%2F%2Fstackblitz.com%2Fedit%2Ficon-button&amp;image=https%3A%2F%2Fc.staticblitz.com%2Fassets%2Ficon-03bbb9acbba813917725387f46e5df03a95d232be240e910ce5f946a973b3f86.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=stackblitz" width="745" height="400" frameborder="0" scrolling="no"><a href="https://medium.com/media/953797eddf3c6684658ab3438f1ba284/href">https://medium.com/media/953797eddf3c6684658ab3438f1ba284/href</a></iframe><h3>More Uses for StackBlitz</h3><p>There is a new version for the <a href="https://stackblitz.com/enterprise">Enterprise</a> that will allow private StackBlitz projects for a company — <a href="https://stackblitz.com/enterprise">on-premise hosting of projects</a>. This will allow for development teams to create and share proof-of-concept (POC) applications.</p><p>Some teams require a StackBlitz proof to accompany a bugfix item. This kind of project could demonstrate the issue with a code sample.</p><p>You could also use a StackBlitz project to target an Angular package — a custom package or a 3rd-party package you want to investigate and learn more about. You can create a POC project with working examples.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=bb64e537d84c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/material-button-with-icon-stackblitz-bb64e537d84c">Material Button with Icon + Stackblitz</a> was originally published in <a href="https://medium.com/angularlicious">angularlicious</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>