<?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: pardeepr08</title>
    <description>The latest articles on DEV Community by pardeepr08 (@pardeepr08).</description>
    <link>https://dev.to/pardeepr08</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%2F1130615%2Fcbde1bfb-c0a2-4e0f-a1a7-5f670494607d.png</url>
      <title>DEV Community: pardeepr08</title>
      <link>https://dev.to/pardeepr08</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pardeepr08"/>
    <language>en</language>
    <item>
      <title>Build your own angular forms - ngModel</title>
      <dc:creator>pardeepr08</dc:creator>
      <pubDate>Tue, 06 Aug 2024 03:43:01 +0000</pubDate>
      <link>https://dev.to/pardeepr08/build-your-own-angular-forms-ngmodel-me8</link>
      <guid>https://dev.to/pardeepr08/build-your-own-angular-forms-ngmodel-me8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;If you are an angular developer, you must have used angular form package many a times in your projects to manage your forms.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are curious to know, what goes behind the scenes to propel such an awesome form management package?&lt;/p&gt;

&lt;p&gt;I am trying to explain and decode angular forms through some series of articles like how angular form package is organized, written and well architected to handle so many different type of form controls and related use cases.&lt;/p&gt;

&lt;p&gt;Don't worry if you feel overwhelmed seeing above flow diagram, we will go through it one component at a time.&lt;/p&gt;

&lt;p&gt;As you already know, ngModel is used to synchronize the values defined in component with any form elements value.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But how ngModel does so?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, let's think over some of the use cases, ngModel should have implemented.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It should accept input property ngModel which will be synchronized with underlying host element.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It should support all different types of form elements like text input, number input, checkbox, select etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It should also work with the custom form elements.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Complexity involved in implementing ngModel directive with above use cases&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As different form elements are dealt differently which means when you write to them, you write to different properties and when you want to track changes in form elemets, you might have to register for different types of events relevant to host element where you apply ngModel directive&lt;/p&gt;

&lt;p&gt;For example, for input having types as text | number | email we will write to the value property but for checkbox we write to the checked property&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Picking the naive approach to design ngModel&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Directive({
  selector: '[ngModel]',
  exportAs: 'ngModel'
})
export class NgModel implements OnChanges {
  @Input('ngModel') model: any
  @Output('ngModelChange') update = new EventEmitter()

  constructor(private _elementRef: ElementRef) {}

  ngOnChanges(changes: SimpleChanges): void {    
    this._elementRef.nativeElement.value = this.model
  }

  @HostListener("input", ["$event.target.value"]) onInput(value: any) {
    this.update.emit(value)
  }
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, as you can see, we inject the elemetRef to get hold of host element and write to it when ngModel input property is passed during change detection and also, we register on host element for the input event and emit updated input value back to the use case component.&lt;/p&gt;

&lt;p&gt;Though simple approach but it has some drawbacks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;If we adopt this approach, it won't scale easily for remaining form controls as different form controls involve some complexity when writing and reading their values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Putting everything in ngModel makes it less configurable and hard to work with custom form elements.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Instead, how angular does it?&lt;/strong&gt;&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Referring to the above diagram, ngModel delegate this responsibility of reading and writing to different types of form elements to different set of directives called control value accessors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;What are control value accessors?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are just simple directives which gets applied to a particular or group of form elements based on their selectors.&lt;/p&gt;

&lt;p&gt;Each control value accessor implements below interface&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export interface ControlValueAccessor {
    writeValue(obj: any): void;
    registerOnChange(fn: any): void;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How it helps ngModel?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each CVA directive is aware of, how to write to particular host element and how to read it by registering to events emitted by host element and thus it frees ngModel from managing the complexity.&lt;/p&gt;

&lt;p&gt;Also these CVA directives expose themselves as a service on a DI token NG_VALUE_ACCESSOR which ngModel can inject and get hold of correct control value accessor to write and read values from host element&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;When ngModel directive is applied on a form element then not only ngModel instance is created but alongwith it an instance of control value accessor directive is also created which is relevant to host element.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Angular provides different types of CVA directive&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;DefaultControlValueAccessor, It is created when applying ngModel on inputs expect the input having type as checkbox.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CheckBoxControlValueAccessor, When applying ngModel on checkbox input, instead of default CVA this is created.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SelectControlValueAccessor, Its created for select box and a few more.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How ngModel integerate with CVA ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Control value accessor directive expose itself as a service on a dependency injection token NG_VALUE_ACCESSOR&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const DEFAULT_VALUE_ACCESSOR: Provider  = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(() =&amp;gt; DefaultControlValueAccessor)
}

@Directive({
    selector: "input:not([type=checkbox])[ngModel]",
    providers: [DEFAULT_VALUE_ACCESSOR]
})
export class DefaultControlValueAccessor extends BaseControlValueAccessor implements ControlValueAccessor {    
    writeValue(value: string): void {
        this.setProperty("value", value)
    }

    @HostListener("input", ["$event.target.value"]) onInput(value: string) {
        this.onChange(value)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ngModel can inject this DI token and get hold of correct CVA directive created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(@Inject(NG_VALUE_ACCESSOR) valueAccessor: ControlValueAccessor) {
    this.valueAccessor = valueAccessor;
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ngModel register itself using registerOnChange method of the injected control value accessor directive instance so that it gets all updates made by user on the host element and thus emit the updated data back to component using ngModelChange event emitter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How ngModel works with custom form elements?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Component({
  selector: 'choose-quantity',
  templateUrl: "choose-quantity.component.html",
  styleUrls: ["choose-quantity.component.scss"],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      multi:true,
      useExisting: ChooseQuantityComponent
    }
  ]
})
export class ChooseQuantityComponent implements ControlValueAccessor {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Actually, what ngModel cares about is control value accessor and a component representing a custom form element can simply implement control value accessor interface and configure itself as a service on the DI token NG_VALUE_ACCESSOR&lt;/p&gt;

&lt;p&gt;Please share your thought and doubts in the comment section.&lt;/p&gt;

&lt;p&gt;If you love exploring the angular form internals and recreate it from scratch with me, you can visit my YouTube channel &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/playlist?list=PLK5nPoSI20qsqg6wIJRXBJiEWwqNg3Vy3" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>angularforms</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Procedural Vs Functional way of solving a JS interview problem</title>
      <dc:creator>pardeepr08</dc:creator>
      <pubDate>Sat, 05 Aug 2023 06:12:28 +0000</pubDate>
      <link>https://dev.to/pardeepr08/procedural-vs-functional-way-of-solving-a-js-interview-problem-peg</link>
      <guid>https://dev.to/pardeepr08/procedural-vs-functional-way-of-solving-a-js-interview-problem-peg</guid>
      <description>&lt;p&gt;Are you also stuck clearing the UI interviews 😕, don’t worry i have a problem for you to practise and learn 😎&lt;/p&gt;

&lt;h2&gt;
  
  
  💡Problem
&lt;/h2&gt;

&lt;p&gt;Write a method called readKey that can access nested properties of an object using a given path.&lt;/p&gt;

&lt;p&gt;Some use case for better understanding the problem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const obj = {
  a: 1,
  b: {
    c: 2,
    d: {
      e: 3
    }
  }
}
console.log(readKey(obj, 'a')); // Output: 1
console.log(readKey(obj, 'b.c')); // Output: 2
console.log(readKey(obj, 'b.d.e')); // Output: 3
console.log(readKey(obj, 'x.y.z')); // Output: undefined (Property not found)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s how i thought of implementing the same using two approaches:&lt;/p&gt;

&lt;h2&gt;
  
  
  Procedural code 😕
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function readKey(obj, path) {
  const keys = path.split('.');
  let result = obj;
  for (const key of keys) {
    if (typeof result === 'object' &amp;amp;&amp;amp; result !== null) {
      result = result[key];
    } else {
      return undefined; // Property not found
    }
  }
  return result;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Functional code 😎
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function readKey(obj, path) {
  return path
    .split('.')
    .reduce((acc, key) =&amp;gt; {
      if (acc !== null &amp;amp;&amp;amp; typeof acc === 'object') {
        return acc[key]
      }
    }, obj)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✋ Ignoring some edge cases in code for the sake of simplicity only.&lt;/p&gt;

&lt;p&gt;Now, comparing both the approaches pros and cons 🤷‍♂️&lt;/p&gt;

&lt;p&gt;To me functional approach is clean, short, abstract and more descriptive. Also shorter the code, less is the surface area for bugs 😁&lt;/p&gt;

&lt;p&gt;On the other side, one can argue that procedural code is more optimized as we cannot break from reduce method when we are sure of not finding the key path in object 🤔 but still i trade that off with code readability 😎&lt;/p&gt;

&lt;p&gt;What is your opinion on this 🤔 ? Please comment.&lt;/p&gt;

&lt;p&gt;If you found this post relevant and worth read, follow me for more …&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>interview</category>
    </item>
    <item>
      <title>Embrace the beauty of map, filter and reduce</title>
      <dc:creator>pardeepr08</dc:creator>
      <pubDate>Tue, 01 Aug 2023 07:39:25 +0000</pubDate>
      <link>https://dev.to/pardeepr08/array-methods-map-filter-and-reduce-3i45</link>
      <guid>https://dev.to/pardeepr08/array-methods-map-filter-and-reduce-3i45</guid>
      <description>&lt;p&gt;It’s rare that you are not asked any questions related to these in your UI interviews. In this post, I am going to discuss the various aspects and importance of these methods and how they can create a shift in your coding style.&lt;/p&gt;

&lt;p&gt;Since we work with arrays most often to collect related data together, many scenarios require operating on arrays, which includes transforming the array, applying filters, or deriving some data out of it.&lt;/p&gt;

&lt;p&gt;These methods rescue us from doing so in many ways in a cleaner and concise way with no side effects involved.&lt;/p&gt;

&lt;p&gt;Before we truly embrace the beauty of these methods, let’s first do these operations in a conventional way we were used to before these landed.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Scenario *&lt;/em&gt;: Given an array having the radius of circles, derive two arrays: one having the circle area and the other having the circumference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Formulas used:&lt;/strong&gt;&lt;br&gt;
PI value = 3.14&lt;br&gt;
Area of a circle = PI * radius * radius&lt;br&gt;
Circumference = 2 * PI * radius&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old school method using for loop:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// calculating circle area
const radius = [1, 2, 3, 4, 5];
const area = [];
for (let i = 0; i &amp;lt; radius.length; i++) {
  area.push(Math.PI * Math.pow(radius[i], 2));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// calculating circle circumference
const circumference = [];
for (let i = 0; i &amp;lt; radius.length; i++) {
  circumference.push(2 * Math.PI * radius[i]);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Using map:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const radius = [1, 2, 3, 4, 5];
const area = radius.map(r =&amp;gt; Math.PI * r * r);
const circumference = radius.map(r =&amp;gt; 2 * Math.PI * r);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can observe, when using the for-loop approach, there is only one change in calculating area and circumference — that is the formula itself, and the iteration part is common and repeating.&lt;/p&gt;

&lt;p&gt;That’s the essence of using map as it abstracts away the iteration part for you, and all you need to focus on is the transformation logic. So your many lines of code are squeezed into just two lines. Isn't it like a magic wand?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Summarizing the benefits of using map over its counterpart for-loop:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Highly readable and concise as it aligns well with functional programming.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Doesn’t mutate the original array but returns a new array with transformed values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inbuilt iteration capability; all I need to care about is passing my transformer function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supports chaining with other array methods like filter, reduce, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Filter and reduce provide similar advantages as map, but these two cater to different use cases as below:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Filter&lt;/strong&gt;: It iterates over the array elements and returns only those elements which pass the filter logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Filter only even numbers from the given array
const numbers = [1, 2, 3, 4, 5];
const evenNumbers = numbers.filter(n =&amp;gt; n % 2 === 0);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Reduce&lt;/strong&gt;: It can be used to derive some data from an array based on the logic passed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Calculate the sum of array elements
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) =&amp;gt; acc + num);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also created some related interview questions as youtube shorts on my channel. Please check if these helps you understand more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtube.com/shorts/-nb7UCukk1A?feature=share"&gt;https://youtube.com/shorts/-nb7UCukk1A?feature=share&lt;/a&gt;&lt;br&gt;
&lt;a href="https://youtube.com/shorts/EvBhdYyFlyc?feature=share"&gt;https://youtube.com/shorts/EvBhdYyFlyc?feature=share&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
