<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Damian Sire (Dev)</title>
    <description>The latest articles on DEV Community by Damian Sire (Dev) (@damiansiredev).</description>
    <link>https://dev.to/damiansiredev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1596605%2Fad6dcbc2-fc46-4102-a686-d89a4abfbc21.png</url>
      <title>DEV Community: Damian Sire (Dev)</title>
      <link>https://dev.to/damiansiredev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/damiansiredev"/>
    <language>en</language>
    <item>
      <title>Evolution in Form Validators: Goodbye customError, Hello Plain Objects</title>
      <dc:creator>Damian Sire (Dev)</dc:creator>
      <pubDate>Thu, 30 Oct 2025 21:42:24 +0000</pubDate>
      <link>https://dev.to/damiansiredev/evolution-in-form-validators-goodbye-customerror-hello-plain-objects-4c35</link>
      <guid>https://dev.to/damiansiredev/evolution-in-form-validators-goodbye-customerror-hello-plain-objects-4c35</guid>
      <description>&lt;p&gt;Form management in Angular, especially with the arrival of &lt;strong&gt;Signal-based forms&lt;/strong&gt;, is constantly evolving to improve ergonomics and the overall &lt;strong&gt;developer experience (DX)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A subtle but incredibly welcome change is the simplification in how we define &lt;strong&gt;custom validation errors&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
What previously required a utility function like &lt;code&gt;customError&lt;/code&gt; to wrap our error object, now allows us to return a &lt;strong&gt;plain JavaScript object (POJO)&lt;/strong&gt; directly.&lt;/p&gt;

&lt;p&gt;This change reduces boilerplate, simplifies the API, and makes creating validators much more intuitive.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;form()&lt;/code&gt; and &lt;code&gt;validate()&lt;/code&gt; APIs discussed here are part of the new Signal-based forms system.&lt;br&gt;&lt;br&gt;
You can explore the implementation details in the Angular PR:&lt;br&gt;&lt;br&gt;
👉 &lt;a href="https://github.com/angular/angular/pull/64339/files" rel="noopener noreferrer"&gt;PR #64339 — Simplify Custom Errors&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  🔑 The Key Change: Before and After
&lt;/h2&gt;

&lt;p&gt;Let's look at a direct comparison — the core of this improvement.&lt;/p&gt;
&lt;h3&gt;
  
  
  Before 👎
&lt;/h3&gt;

&lt;p&gt;Previously, to indicate a custom validation error, we often needed to import and use a utility function to &lt;em&gt;wrap&lt;/em&gt; our error and ensure it was correctly typed and recognized by the forms system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;customError&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some-forms-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// We needed the customError wrapper&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;p&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;customError&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;i am a custom error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  🧩 Simplified Validator API in Angular Signal Forms
&lt;/h1&gt;

&lt;p&gt;With the new simplified API, the validation engine is smart enough to understand a simple object as an error response.&lt;br&gt;&lt;br&gt;
If the validator function returns an object, it's an error.&lt;br&gt;&lt;br&gt;
If it returns &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;, it's valid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;form&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// We simply return the error object&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;p&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;iAmACustomError&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt; &lt;span class="c1"&gt;// Much cleaner!&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Valid&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💡 Why Does This Change Matter?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🚫 Less Boilerplate
&lt;/h3&gt;

&lt;p&gt;You no longer need to import &lt;code&gt;customError&lt;/code&gt; in every validator file.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 More Intuitive API
&lt;/h3&gt;

&lt;p&gt;The flow feels natural — &lt;em&gt;"Is there an error? If so, return the error object."&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 Easier Testing
&lt;/h3&gt;

&lt;p&gt;Mocking or stubbing a validator is trivial when it just returns an object.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Consistency
&lt;/h3&gt;

&lt;p&gt;It aligns with how synchronous validators work in traditional reactive forms (&lt;code&gt;Validators.required&lt;/code&gt; returns &lt;code&gt;{ required: true }&lt;/code&gt;).&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;While this might seem like a small change, it’s a perfect example of Angular’s ongoing effort to make APIs simpler, more consistent, and more developer-friendly.&lt;/p&gt;

&lt;p&gt;Cleaner validators mean fewer imports, less friction, and a smoother DX overall — especially as Signal-based forms continue to mature.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>signals</category>
      <category>forms</category>
    </item>
    <item>
      <title>File Naming Conventions: Keep Your Project Clean and Readable ✨</title>
      <dc:creator>Damian Sire (Dev)</dc:creator>
      <pubDate>Sat, 27 Sep 2025 19:17:16 +0000</pubDate>
      <link>https://dev.to/damiansiredev/file-naming-conventions-keep-your-project-clean-and-readable-1plk</link>
      <guid>https://dev.to/damiansiredev/file-naming-conventions-keep-your-project-clean-and-readable-1plk</guid>
      <description>&lt;p&gt;Ever jumped into an Angular project and felt lost in a sea of confusing file names? 🌊 Consistent naming isn't just about being tidy; it's a cornerstone of professional, maintainable, and team-friendly code. When your file structure is predictable, you spend less time searching and more time coding.&lt;/p&gt;

&lt;p&gt;Let's break down some simple but powerful file naming conventions from the official Angular style guide that will make your life (and your teammates' lives) much easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate Words with Hyphens (Kebab-Case)
&lt;/h2&gt;

&lt;p&gt;This is the foundational rule. Always separate words in your file names with hyphens. This convention, often called &lt;strong&gt;kebab-case&lt;/strong&gt;, is a standard in web development and makes file names easy to read.&lt;/p&gt;

&lt;p&gt;For example, if you have a component class named &lt;code&gt;UserProfileComponent&lt;/code&gt;, its file name should be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;user-profile.component.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is much clearer and more conventional than &lt;code&gt;userprofile.ts&lt;/code&gt; or &lt;code&gt;user_profile.ts&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Name Test Files with &lt;code&gt;.spec&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Your unit tests are first-class citizens in your project and should be easy to find. The standard is to use the exact same name as the file you are testing, but with a &lt;code&gt;.spec.ts&lt;/code&gt; suffix.&lt;/p&gt;

&lt;p&gt;This pattern is instantly recognizable and is the default configuration for testing frameworks like Karma and Jest in the Angular ecosystem.&lt;/p&gt;

&lt;p&gt;For our &lt;code&gt;user-profile.component.ts&lt;/code&gt; file, the corresponding test file would be:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;user-profile.component.spec.ts&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Match the File Name to Its Contents
&lt;/h2&gt;

&lt;p&gt;A file's name should be a clear signpost to what's inside. When a file contains a primary identifier, like a TypeScript &lt;code&gt;class&lt;/code&gt;, the file name should be the kebab-case version of that identifier.&lt;/p&gt;

&lt;p&gt;For instance, a file containing the class &lt;code&gt;OrderHistoryService&lt;/code&gt; should be named:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;order-history.service.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A quick tip:&lt;/strong&gt; Avoid overly generic file names like &lt;code&gt;helpers.ts&lt;/code&gt;, &lt;code&gt;utils.ts&lt;/code&gt;, or &lt;code&gt;common.ts&lt;/code&gt;. While tempting, these files often become a dumping ground for unrelated code, making them hard to maintain. If you have several unrelated helper functions, consider breaking them into separate, more specific files (e.g., &lt;code&gt;string-formatters.ts&lt;/code&gt;, &lt;code&gt;validation-rules.ts&lt;/code&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Group Component Files by Name
&lt;/h2&gt;

&lt;p&gt;A typical Angular component is made up of several files: the TypeScript logic, the HTML template, and the CSS/SCSS styles. To keep these related files neatly grouped and easy to locate, they should all share the same base name.&lt;/p&gt;

&lt;p&gt;Following our &lt;code&gt;UserProfileComponent&lt;/code&gt; example, its complete set of files would look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;user-profile.component.ts&lt;/code&gt; (the component class)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user-profile.component.html&lt;/code&gt; (the template)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user-profile.component.scss&lt;/code&gt; (the styles)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it incredibly simple to find all the pieces of a single component.&lt;/p&gt;

&lt;p&gt;What if a component has multiple style files? Just append a descriptive word. For example, you might have styles specific to different themes or sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;user-profile-light.scss&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;user-profile-dark.scss&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does This Matter? 🤔
&lt;/h2&gt;

&lt;p&gt;Following these conventions brings huge benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readability:&lt;/strong&gt; Your project becomes instantly easier to scan and understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Findability:&lt;/strong&gt; You can find any file you need quickly, without guesswork.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; It creates a professional and predictable structure, which is crucial when working on a team.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tooling:&lt;/strong&gt; Many CLI commands and IDE extensions rely on these conventions to generate, find, and link code correctly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By adopting these simple naming rules, you're not just organizing files—you're building a more professional, scalable, and enjoyable Angular application. &lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Is ViewChild and Lifecycle Hooks in Angular Really Code Smells? No.</title>
      <dc:creator>Damian Sire (Dev)</dc:creator>
      <pubDate>Fri, 18 Apr 2025 13:21:13 +0000</pubDate>
      <link>https://dev.to/damiansiredev/is-viewchild-and-lifecycle-hooks-in-angular-really-code-smells-no-29me</link>
      <guid>https://dev.to/damiansiredev/is-viewchild-and-lifecycle-hooks-in-angular-really-code-smells-no-29me</guid>
      <description>&lt;h2&gt;
  
  
  Demystifying &lt;code&gt;ViewChild&lt;/code&gt; in Angular: Useful Tool or Code Smell?
&lt;/h2&gt;

&lt;p&gt;In recent discussions within the Angular development community, the use of &lt;code&gt;ViewChild&lt;/code&gt; has been labeled by some as a "code smell." Supporters of this view argue it's often unnecessary, even comparing it to the redundancy of certain lifecycle hooks like &lt;code&gt;ngAfterViewInit&lt;/code&gt;, claiming that setter functions on the &lt;code&gt;@ViewChild&lt;/code&gt; property are enough.&lt;/p&gt;

&lt;p&gt;However, this perspective oversimplifies both the utility of &lt;code&gt;ViewChild&lt;/code&gt; and the core purpose of Angular lifecycle hooks. &lt;code&gt;ViewChild&lt;/code&gt; is a decorator provided by Angular to allow a parent component to access child component instances, directives, or DOM elements within its template. Like any powerful tool, &lt;strong&gt;misuse&lt;/strong&gt; can lead to design issues, and it's this misuse that might be a code smell—not the tool itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Can &lt;code&gt;ViewChild&lt;/code&gt; Be Problematic?
&lt;/h2&gt;

&lt;p&gt;Labeling &lt;code&gt;ViewChild&lt;/code&gt; as &lt;em&gt;always&lt;/em&gt; a code smell is an overgeneralization. However, some usage patterns should raise concerns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Excessive Parent-to-Child Communication:&lt;/strong&gt; If you're constantly using &lt;code&gt;ViewChild&lt;/code&gt; to call methods or set properties on child components, you're likely creating tight coupling. Instead, consider using &lt;code&gt;@Input()&lt;/code&gt; to pass data and &lt;code&gt;@Output()&lt;/code&gt; with &lt;code&gt;EventEmitter&lt;/code&gt; to notify the parent. Shared services are another excellent alternative.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Direct DOM Manipulation:&lt;/strong&gt; Using &lt;code&gt;ViewChild&lt;/code&gt; to access an &lt;code&gt;ElementRef&lt;/code&gt; and manipulate the DOM goes against Angular's abstractions. While sometimes necessary (e.g., integrating third-party libraries), Angular often provides idiomatic alternatives like property binding, attribute binding, or custom directives.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In short, if you're using &lt;code&gt;ViewChild&lt;/code&gt; for fine-grained control or DOM manipulation without a solid reason, it's time to reconsider. Explore &lt;code&gt;@Input()&lt;/code&gt;, &lt;code&gt;@Output()&lt;/code&gt;, or services instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setter vs. &lt;code&gt;ngAfterViewInit&lt;/code&gt;: Not Interchangeable
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;ViewChild&lt;/code&gt; setter is &lt;strong&gt;not&lt;/strong&gt; a replacement for &lt;code&gt;ngAfterViewInit&lt;/code&gt;. Setters run when that specific reference becomes available. In contrast, &lt;code&gt;ngAfterViewInit&lt;/code&gt; runs &lt;strong&gt;after&lt;/strong&gt; the component's full view and all child views are initialized.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multiple Dependencies:&lt;/strong&gt; If your logic depends on several &lt;code&gt;ViewChild&lt;/code&gt; or &lt;code&gt;ViewChildren&lt;/code&gt; references, &lt;code&gt;ngAfterViewInit&lt;/code&gt; ensures they’re all ready.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full View State Dependency:&lt;/strong&gt; Sometimes your code needs the final rendered view (e.g., dimensions or position). &lt;code&gt;ngAfterViewInit&lt;/code&gt; is the right hook for this.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Valid Use Cases for &lt;code&gt;ViewChild&lt;/code&gt; and &lt;code&gt;ngAfterViewInit&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Here are legitimate scenarios where &lt;code&gt;ViewChild&lt;/code&gt; and &lt;code&gt;ngAfterViewInit&lt;/code&gt; are appropriate:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Integrating External JavaScript Libraries
&lt;/h3&gt;

&lt;p&gt;Chart.js or Swiper might require a direct DOM reference. Use &lt;code&gt;ViewChild&lt;/code&gt; to grab it, and &lt;code&gt;ngAfterViewInit&lt;/code&gt; to safely initialize.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Chart&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chart.js/auto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// example with Chart.js&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-chart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;canvas #myCanvas&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChartComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;myCanvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;myCanvas&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLCanvasElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;chart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;ngAfterViewInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myCanvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;chart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* data */&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* options */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Could not get the 2D context from the canvas.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the previous case, there is no doubt that it is a good path. Now come cases where consensus is not entirely clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Possibles valid Use Case for ViewChild and ngAfterViewInit (Although frankly, I would use a directive)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Post-Render UI Logic (Also check example 5)
&lt;/h3&gt;

&lt;p&gt;Tooltip positioning, layout adjustments, and viewport visibility checks require post-render DOM access. &lt;code&gt;ngAfterViewInit&lt;/code&gt; ensures proper timing.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Directives Affecting Multiple Children
&lt;/h3&gt;

&lt;p&gt;For example, a directive that styles table rows via &lt;code&gt;@for&lt;/code&gt;. You need &lt;code&gt;ngAfterViewInit&lt;/code&gt; or &lt;code&gt;ngAfterContentInit&lt;/code&gt; and &lt;code&gt;@ViewChildren&lt;/code&gt; or &lt;code&gt;@ContentChildren&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dynamic Dimension Calculations and Positioning
&lt;/h3&gt;

&lt;p&gt;You often encounter scenarios where you must perform tasks based on the actual size and position of elements only after the browser has rendered them. Common examples include calculating one element's height to adjust another's layout, checking if an element is currently visible within the viewport, dynamically positioning tooltips or popovers relative to their trigger elements, or implementing complex, responsive layouts such as a masonry grid. These operations depend critically on knowing the final computed dimensions and placement.&lt;/p&gt;

&lt;p&gt;The reason these calculations require the fully rendered view is fundamental to how web browsers work. The true dimensions (obtainable via properties like offsetWidth, offsetHeight, or methods like getBoundingClientRect()) and exact positions of elements are only finalized once the browser has processed the HTML structure, applied all relevant CSS styles, and completed the layout rendering pass. Attempting to measure elements before this stage often yields inaccurate or incomplete data.&lt;/p&gt;

&lt;p&gt;Within an Angular application, the ngAfterViewInit lifecycle hook is specifically designed for these initial post-render calculations, firing after the component's view and child views are fully initialized. If dimensions or positions need to be recalculated later due to dynamic changes (like data updates or window resizing), you might use ngAfterViewChecked (being careful about performance) or, preferably, leverage more modern and efficient browser APIs like ResizeObserver to react specifically to element size modifications.&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-tooltip-host&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;button #trigger (mouseenter)="showTooltip()" (mouseleave)="hideTooltip()"&amp;gt;Hover me&amp;lt;/button&amp;gt;
    &amp;lt;div #tooltip class="tooltip" [style.visibility]="visible ? 'visible' : 'hidden'"&amp;gt;
      Tooltip content!
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`.tooltip { position: absolute; /* ... other styles ... */ }`&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TooltipHostComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trigger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tooltip&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;tooltip&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Renderer2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;ngAfterViewInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// You could do an initial calculation here if necessary,&lt;/span&gt;
    &lt;span class="c1"&gt;// but the main logic is triggered by events.&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="nf"&gt;showTooltip&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// Short delay to ensure the tooltip is visible BEFORE measuring&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;positionTooltip&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Call renamed function&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;hideTooltip&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;positionTooltip&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Ensure it's visible to measure&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;triggerRect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Needs to be rendered and visible!&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tooltipRect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBoundingClientRect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tooltipElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tooltip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Example: Position above the trigger&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;triggerRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;tooltipRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 5px of space&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;triggerRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;triggerRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tooltipRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Simple logic to prevent it from going off the top (could be more complex)&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Position below if it doesn't fit above&lt;/span&gt;
        &lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;triggerRect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Adjust for scroll&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tooltipElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;top&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Adjust for scroll&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tooltipElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;left&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scrollX&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;px`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ViewChild&lt;/code&gt; isn't inherently bad or a code smell. It’s a specific tool for specific jobs in Angular. Rejecting it entirely—or thinking a setter replaces it—ignores valid use cases and lifecycle guarantees.&lt;/p&gt;

&lt;p&gt;The key is understanding its purpose and recognizing signs of design issues, like tight coupling or unjustified DOM manipulation.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
