<?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[angularlicious - Medium]]></title>
        <description><![CDATA[Articles about implementing enterprise patterns and principles in Angular applications. Learn how to implement Angular tooling like Schematics, Custom Libraries, and cross-cutting concerns to create amazing apps. - Medium]]></description>
        <link>https://medium.com/angularlicious?source=rss----2772504e0c23---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>angularlicious - Medium</title>
            <link>https://medium.com/angularlicious?source=rss----2772504e0c23---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 21:16:20 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/angularlicious" 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----2772504e0c23---4</link>
            <guid isPermaLink="false">https://medium.com/p/828dd650e86b</guid>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Thu, 14 Nov 2024 19:56:26 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 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----2772504e0c23---4</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----2772504e0c23---4</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----2772504e0c23---4</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----2772504e0c23---4</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----2772504e0c23---4</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[Keep Your Nx Workspace Clean with ESLint]]></title>
            <link>https://medium.com/angularlicious/keep-your-nx-workspace-clean-with-eslint-7dcb328910ac?source=rss----2772504e0c23---4</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:33:47 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----2772504e0c23---4</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>Sat, 28 Nov 2020 03:36:38 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>
        <item>
            <title><![CDATA[Use RxJS to Push Configuration to Angular Libraries]]></title>
            <link>https://medium.com/angularlicious/use-rxjs-to-push-configuration-to-angular-libraries-1c47830cc394?source=rss----2772504e0c23---4</link>
            <guid isPermaLink="false">https://medium.com/p/1c47830cc394</guid>
            <category><![CDATA[angular-configuration]]></category>
            <category><![CDATA[angular8]]></category>
            <category><![CDATA[angular2]]></category>
            <category><![CDATA[angularlicious]]></category>
            <category><![CDATA[angular-library]]></category>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Wed, 26 Jun 2019 03:22:41 GMT</pubDate>
            <atom:updated>2019-06-23T16:25:07.152Z</atom:updated>
            <content:encoded><![CDATA[<h4>Angular libraries are much better with configuration using RxJS, interfaces, and typed configuration.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*zzoaAG26kzzsdyV1_g6p7g.jpeg" /></figure><p>A working solution is available on Github at:</p><p><a href="https://github.com/angularlicious/configuration-for-libraries">angularlicious/configuration-for-libraries</a></p><p>The Angular Workspace provides the ability to have multiple library and application projects in a single environment. Although this capability has been available since version 6, I find that many developers and teams are not taking full advantage of shared libraries. Having the ability to share and reuse code in the form of libraries adds to the effectiveness of your development team.</p><p>Think of the many shared libraries that would benefit your Angular applications. Here is a list of different library types that are common to applications.</p><ul><li>features</li><li>cross-cutting concerns</li><li>utilities</li><li>frameworks</li><li>foundational</li></ul><p>There are many opportunities to create libraries for our Angular applications. However, one of the difficulties is getting the configuration to these libraries. This post will demonstrate how an Angular application can provide configuration to Libraries in an Angular Workspace environment. The focus will be on providing configuration to libraries. The <em>Logging</em> and <em>ErrorHandling</em> libraries volunteered to participate in this demonstration. However, the process and patterns could be used for any type of library in the Workspace.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*P9sh4DTkZkBlL02P8hV1Fg.png" /></figure><h3>What We Get from Angular</h3><p>Angular applications have an <em>environment</em> context that provides configuration items targeting specific environments for the application. Angular libraries in the <em>Workspace</em> cannot access the <em>environment</em> context. Applications reference and use libraries — and Angular Libraries may reference and use other libraries. If libraries had access to the <em>environment</em> context it would cause a circular dependency.</p><p>One of the main tenets of developing reusable libraries is to keep them generic enough to be reused by many applications and libraries. Therefore, the next evolution of the target library is to create a <em>configuration</em> for elements that can vary. Therefore, libraries need configuration.</p><blockquote><em>Note: Not all library projects need configuration, but when they do, they prefer it pushed.</em></blockquote><h3>Libraries Need Configuration Too</h3><p>The target Angular application is the source of the configuration and has the responsibility to provide that configuration to the specified library items. Since the environment context is part of the Application’s domain, the library cannot reference and use this for its configuration.</p><blockquote><em>Note: The </em><em>environment context is an object with data elements. It is not strongly typed in terms of its schema. However, the members of the </em>environment<em> context are typed - however, there is not defined object type.</em></blockquote><p>No need to worry, we can use some simple patterns and create a strongly-typed mechanism for library configuration.</p><h3>Provide Strongly-Typed Configuration to Angular Libraries</h3><p>Here is what needs to happen to enable configuration for libraries.</p><ol><li>each <em>library</em> will define its own <em>configuration</em> schema or object type</li><li>each <em>library</em> will define an <em>interface</em> for the structure of the specific configuration</li><li>each <em>library</em> will subscribe to <em>publish</em> events of configuration</li><li>library configuration will be <em>pushed</em> to libraries</li><li>each <em>library</em> has the responsibility to validate the configuration provided</li><li>each <em>library</em> has the responsibility to define default values for any required items.</li><li>each <em>application</em> will retrieve the <em>configuration</em></li><li>a <em>service</em> will provide the mechanism to <em>publish</em> configuration to library subscribers.</li></ol><p>The <em>linchpin</em> in this scenario will be a new Configuration service that will act as a mediator between applications with configuration and the libraries that need that configuration. It is following an inversion of control pattern where libraries cannot retrieve or instantiate their own configuration — it will be provided to them. Applications will use the new <em>ConfigurationS</em>ervice to publish configuration.</p><blockquote><em>The main goal is to use a push strategy. The libraries should not pull or request their own configuration. It is not their responsibility to have such knowledge. Therefore, we will let the libraries react to published events of configuration when applications provide it.</em></blockquote><h3>Configuration Library</h3><p>Create a new library in your Angular Workspace. It will be used to mediate the transfer of configuration information from applications to libraries with configuration requirements.</p><pre>ng generate library configuration --publishable --unit-test-runner=jest</pre><p>Add a new <em>ConfigurationService</em> to the library. This is a very straight-forward service. It does one thing and it does it very well. It provides the configuration from the application to any subscribers. The target subscribers in our context are libraries. However, the service could also be used by other modules, components, and services within the application.</p><ul><li>the settings$ is a <a href="https://rxjs-dev.firebaseapp.com/api/index/class/ReplaySubject">ReplaySubject</a> that buffers a set of values and emits the values immediately to subscribers</li><li>the ReplaySubject will buffer or keep the <em>one</em> configuration available to emit to all subscribers no matter when or where they subscribe.</li><li>a <em>ConfigurationContext</em> is injected into the constructor of the service.</li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4acba07acbd5d3cd4ad36506197f877c/href">https://medium.com/media/4acba07acbd5d3cd4ad36506197f877c/href</a></iframe><p>The <em>ConfigurationContext</em> is just a container class for anything that can be provided to the ConfigurationModule and made available to members of that module, like the <em>ConfigurationService</em>. We could pass the actual configuration directly, but I like to keep my options open for future opportunities.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/10a1398d139646eb1e0845eb7700f56c/href">https://medium.com/media/10a1398d139646eb1e0845eb7700f56c/href</a></iframe><h3>Interface-Driven Configuration</h3><p>Notice that the settings$ ReplaySubject is of type IConfiguration. We are using an interface-driven approach to allow the interfaces to define the types for each library configuration. The IConfiguration provides the container type for all configuration members.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/364a1b59df00eb02c061f0a3bba4ed3a/href">https://medium.com/media/364a1b59df00eb02c061f0a3bba4ed3a/href</a></iframe><h3>Providing the Configuration to Libraries</h3><p>If you are wondering how the <em>ConfigurationContext</em> is provided to the <em>ConfigurationModule</em>, the library’s module has a static forRoot() method to allow applications to provide the library with the specified configuration.</p><p>The <em>ConfigurationContext</em> is just a class to define the members of the context. Currently, it only has a <em>config</em> property. The members of this class are available to the ConfigurationModule when they are set as one of the providers of the module. Basically, the forRoot() allows the module to have the input setup as a provider - the <em>ConfigurationContext</em> is now available for dependency injection. The service now has direct access to this input because it is injected into the constructor of the <em>ConfigurationService</em>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dfde3670577238da227d2d7e7a03de42/href">https://medium.com/media/dfde3670577238da227d2d7e7a03de42/href</a></iframe><p>The <em>ConfigurationService</em> in the ConfigurationModule contains a public <em>ReplaySubject</em>. The ConfigurationService is injected into the constructor of the service. This allows the <em>LoggingService</em> to subscribe to <em>configuration</em> events from the ConfigurationService. When the configuration is emitted, this service will use the provided value (i.e., IConfiguration ).</p><p>The log() method allows the <em>LoggingService</em> to emit a new LogEntry item. The LogWriters configured by the application will respond by sending the specified log entry to the target repository and/or the console. To recap, the LoggingService only does (2) things:</p><ol><li>uses the LoggingConfig provided by the ConfigurationService to set up some of the logging information</li><li>creates LogEntry items and publishes them to subscribed log writers.</li></ol><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/afcedbb98700da7459fe0470f7574141/href">https://medium.com/media/afcedbb98700da7459fe0470f7574141/href</a></iframe><h3>Library Configuration Recipe</h3><p>This is a functional logging service that can be used by any number of applications and also by other Angular libraries. This is an important part of the library configuration recipe.</p><ol><li>a <em>ConfigurationService</em> is <strong>injected </strong>into the service constructor.</li><li>the service <strong>subscribes </strong>to the <em>ReplaySubject</em> for configuration events.</li><li>the service <strong>handles </strong>a configuration value emitted by the ReplaySubject.</li><li>the service can <strong>validate </strong>and provide any required <strong>default </strong>values based on the configuration</li></ol><blockquote>Note: You can learn more about the log writers by reviewing the code in the GitHub repository. <a href="https://github.com/angularlicious/configuration-for-libraries">https://github.com/angularlicious/configuration-for-libraries</a></blockquote><h3>Application Configuration</h3><p>The actual configuration for the application should be consistent and typed. It should also be environment specific. Therefore, the application should have a configuration defined for each application environment. Use the same convention of the <em>environment</em> constant.</p><ul><li>app.config.development.ts</li><li>app.config.stage.ts</li><li>app.config.production.ts</li></ul><p>The <em>AppConfig</em> shown below shows the implementation of an application configuration. This configuration is typed and is based on interfaces. Since it is a Typescript object, there is no need to load the configuration using HTTP or importing a JSON file.</p><blockquote><em>Note: Originally, the solution used JSON files for the configuration. The application imported the JSON file or supplied the path to the file to an HTTP GET call. This could work well in a scenario where you would like to replace the JSON file during the CI/Build process for specific environments. Keep important or private information secure!</em></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/caac3eeb4b0898adca1770efd94a1521/href">https://medium.com/media/caac3eeb4b0898adca1770efd94a1521/href</a></iframe><p>Now, each environment (i.e., development, stage, or production) can target the specified configuration and make it available using the appConfig property of the <em>environment</em> object.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1841d9b2c8de84694f93314151b1975a/href">https://medium.com/media/1841d9b2c8de84694f93314151b1975a/href</a></iframe><p>The application’s configuration is now ready. The <em>ConfigurationModule</em> is imported and the application’s configuration is provided to the module using the static forRoot() method. This module has the responsibility to load the library services and to provide the configuration.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f51f5fc48d1f4b97e070fade99b42fd/href">https://medium.com/media/1f51f5fc48d1f4b97e070fade99b42fd/href</a></iframe><h3>Conclusion: (Bonus: Plug-in Services)</h3><p>Notice that the module is using the APP_INITIALIZER to initialize the log <em>writers</em>. What are log writers? Well, the LoggingService has the responsibility to provide an endpoint for the application to send a log message and other details. The <em>writers</em> have the responsibility to write/send the message to a target. The <em>ConsoleWriter</em> simply logs events to the browser&#39;s console. You can view the log messages in the developer tools console. This works great for development. However, in non-production environments, the log items should be stored in a centralized repository.</p><p>The <em>LogglyWriter</em> writes the log messages to <a href="https://www.loggly.com/">Loggly</a> — a cloud-based provider. This implementation uses <a href="https://www.loggly.com/">Loggly</a> for a centralized repository of application logs. There are several cloud-based solutions to choose for centralized logging. A centralized repository allows you to monitor, filter, and analyze log events for your Angular applications.</p><p>All of this made possible using Angular Libraries and typed Configuration from the application. More information about Angular Workspace and the <a href="https://angularlicio.us/podcast">Angularlicious Podcast</a> at <a href="https://angularlicio.us./">https://angularlicio.us</a> — or on Twitter <a href="https://twitter.com/angularlicious">@angularlicious</a>.</p><ul><li><a href="https://github.com/angularlicious/configuration-for-libraries">angularlicious/configuration-for-libraries</a></li><li><a href="https://twitter.com/angularlicious">Angularlicious (@angularlicious) | Twitter</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c47830cc394" width="1" height="1" alt=""><hr><p><a href="https://medium.com/angularlicious/use-rxjs-to-push-configuration-to-angular-libraries-1c47830cc394">Use RxJS to Push Configuration to Angular Libraries</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[Add and Debug Schematic Projects in an Angular Workspace]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/angularlicious/add-and-debug-schematic-projects-in-an-angular-workspace-c037fbe2930e?source=rss----2772504e0c23---4"><img src="https://cdn-images-1.medium.com/max/1125/1*N0SuexicwnzgPuCAbuvjtg.png" width="1125"></a></p><p class="medium-feed-snippet">Learn how to integrate Schematics development in your Angular Workspace (Monorepo).</p><p class="medium-feed-link"><a href="https://medium.com/angularlicious/add-and-debug-schematic-projects-in-an-angular-workspace-c037fbe2930e?source=rss----2772504e0c23---4">Continue reading on angularlicious »</a></p></div>]]></description>
            <link>https://medium.com/angularlicious/add-and-debug-schematic-projects-in-an-angular-workspace-c037fbe2930e?source=rss----2772504e0c23---4</link>
            <guid isPermaLink="false">https://medium.com/p/c037fbe2930e</guid>
            <category><![CDATA[angularlicious-podcast]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[matt-vaughn]]></category>
            <category><![CDATA[angularlicious]]></category>
            <category><![CDATA[npm-angularlicious]]></category>
            <dc:creator><![CDATA[Matt Vaughn]]></dc:creator>
            <pubDate>Sat, 24 Nov 2018 01:59:48 GMT</pubDate>
            <atom:updated>2018-11-25T06:35:39.066Z</atom:updated>
        </item>
    </channel>
</rss>