<?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: Sajeeb Ahamed</title>
    <description>The latest articles on DEV Community by Sajeeb Ahamed (@ahamed_).</description>
    <link>https://dev.to/ahamed_</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%2F245880%2F995491e9-5790-4f45-b7bb-2c8ece1917ee.jpg</url>
      <title>DEV Community: Sajeeb Ahamed</title>
      <link>https://dev.to/ahamed_</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ahamed_"/>
    <language>en</language>
    <item>
      <title>Create an Enum representation in JavaScript using Proxy object.</title>
      <dc:creator>Sajeeb Ahamed</dc:creator>
      <pubDate>Tue, 09 Aug 2022 19:03:00 +0000</pubDate>
      <link>https://dev.to/ahamed_/create-an-enum-representation-in-javascript-using-proxy-object-42o5</link>
      <guid>https://dev.to/ahamed_/create-an-enum-representation-in-javascript-using-proxy-object-42o5</guid>
      <description>&lt;p&gt;And finally, I've found a real use-case of a Proxy object in JavaScript. Many developers love to use &lt;code&gt;enums&lt;/code&gt; in their code but as a JavaScript developer, you don't have the opportunity to use that cool feature.&lt;/p&gt;

&lt;p&gt;As there is no such feature in JavaScript, let's create a custom implementation of &lt;strong&gt;creating an enum&lt;/strong&gt;. No more talking, deep dive into the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createEnum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&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;structure&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' is not a valid enum structure.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&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;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s2"&gt;`You are only allowed to use 'number', 'string' or 'boolean' types, but you are using '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&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="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="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&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="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Cannot assign to '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' because it is a read-only property.`&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="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Property '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' does not exist on the enum structure.`&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&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="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&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;h3&gt;
  
  
  Create the function
&lt;/h3&gt;

&lt;p&gt;Here, we are creating a &lt;code&gt;createEnum&lt;/code&gt; function, that accepts a parameter &lt;code&gt;structure&lt;/code&gt;. This &lt;code&gt;structure&lt;/code&gt; is a plain object like &lt;code&gt;[key: string]: number | string | boolean&lt;/code&gt;. So, what does it mean?&lt;/p&gt;

&lt;p&gt;This means the &lt;code&gt;structure&lt;/code&gt; object only supports a string type key and a string or number or boolean type value. For example-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ACCEPTED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accepted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;REJECTED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rejected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we are trying to create a utility function and want other developers to use that function, so, we have to do some sanitization.&lt;/p&gt;

&lt;h3&gt;
  
  
  First check if the structure is an object or not.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&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;structure&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' is not a valid enum structure.`&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;In the code above, we are checking if the &lt;code&gt;structure&lt;/code&gt; is an object or not. We can easily check whether a variable is an object or not by checking its type (&lt;code&gt;typeof structure === 'object'&lt;/code&gt;). But the problem is &lt;code&gt;typeof null&lt;/code&gt; and &lt;code&gt;typeof []&lt;/code&gt; also return 'object'. So, we have to keep in mind those cases as well.&lt;/p&gt;

&lt;h3&gt;
  
  
  If the structure is an object, then check the object is a valid one.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;for&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;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`You are only allowed to use 'number', 'string' or 'boolean' types, but you are using '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&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="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;Previously we are checking whether the &lt;code&gt;structure&lt;/code&gt; param is an object or not. If this is an object, then we have to check the validity of that object's values. For an enum, we can only assign &lt;code&gt;string | number | boolean&lt;/code&gt; type values.&lt;/p&gt;

&lt;p&gt;In the code above we are checking all the properties of the &lt;code&gt;structure&lt;/code&gt; object, and if there is any value that exists which is not a &lt;code&gt;number&lt;/code&gt; or &lt;code&gt;string&lt;/code&gt; or &lt;code&gt;boolean&lt;/code&gt; then throw an error.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finished the sanitization. Now it's time to create the &lt;code&gt;Proxy&lt;/code&gt;.
&lt;/h3&gt;

&lt;p&gt;We've completed our sanitization for the &lt;code&gt;structure&lt;/code&gt; param. Now create the enum.&lt;/p&gt;

&lt;p&gt;Our goals are -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating an object which is not extendable and changeable a.k.a not modifiable.&lt;/li&gt;
&lt;li&gt;If someone tries to modify it, then throw an error.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can easily prevent an object from being modified by using the &lt;code&gt;Object.freeze()&lt;/code&gt; function. But the problem is that &lt;code&gt;Object.freeze()&lt;/code&gt; won't throw an error if you try to change a property or add a new property. Then how could we do that?&lt;/p&gt;

&lt;p&gt;Here, the &lt;code&gt;Proxy&lt;/code&gt; comes as a rescuer.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In short, a &lt;code&gt;Proxy&lt;/code&gt; accepts a target object and can listen to any change in the target object and return a new object. For more about proxy you can &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy"&gt;read this&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One of our goals is to prevent the modification of the &lt;code&gt;structure&lt;/code&gt; object's properties and throw errors if any modification happens. By using the &lt;code&gt;set&lt;/code&gt; handler function we can do it easily.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&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="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Cannot assign to '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' because it is a read-only property.`&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="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Property '&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;' does not exist on the enum structure.`&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="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&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="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&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;Inside the &lt;code&gt;set&lt;/code&gt; handler function we are simply throwing some errors and this simple trick prevents us to modify any property to that object. Here, we are checking if the changing property already exists in the object or not. If it exists that means we are trying to change an existing property, otherwise we are trying to add some new property. In these cases, we are throwing two separate errors.&lt;/p&gt;

&lt;p&gt;And also, a question may arise in your mind, what the heck is this &lt;code&gt;Reflect&lt;/code&gt; thing doing here? According to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect"&gt;MDN&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Reflect is a built-in object that provides methods for &amp;gt;interceptable JavaScript operations. The methods are the same as those of proxy handlers. Reflect is not a function object, so it's not constructible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;get&lt;/code&gt; function of the proxy handler is just returning the respective value of a property.&lt;/p&gt;

&lt;h3&gt;
  
  
  Doing a lot of things. Now it's time to test the function.
&lt;/h3&gt;

&lt;p&gt;Yes, this is the exciting moment of testing our implementation. Let's do it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createEnum&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ACCEPTED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;accepted&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;REJECTED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rejected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bingo! we have created our first enum 🎉. Now we can use that enum like &lt;code&gt;Status.PENDING&lt;/code&gt;, &lt;code&gt;Status.ACCEPTED&lt;/code&gt;, ... etc. But wait, how does it being different from a regular object?&lt;/p&gt;

&lt;p&gt;I think you've already guessed the difference. If we try to do something like this-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ❌ Invalid assignment&lt;/span&gt;
&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PENDING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Error: Cannot assign to 'PENDING' because it is a read-only property.&lt;/span&gt;
&lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NEW_VALUE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new-value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//Error: Property 'NEW_VALUE' does not exist on the enum structure.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This change will cause you an error that does not happen for a normal object.&lt;/p&gt;

&lt;h3&gt;
  
  
  See a real use-case for this enum.
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3423&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ The condition is true&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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PENDING&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Pending user&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we used the enum to an almost real scenario 😛. We declared a &lt;code&gt;user&lt;/code&gt; object and for the &lt;code&gt;status&lt;/code&gt; property, we assigned a value from the &lt;code&gt;Status&lt;/code&gt; enum. Also, we are checking the &lt;code&gt;user.status&lt;/code&gt; with the &lt;code&gt;Status&lt;/code&gt; enum.&lt;/p&gt;

&lt;p&gt;We did it... 🎉 🎉 🎉&lt;/p&gt;

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

&lt;p&gt;From this article we are going to know about &lt;code&gt;Enums&lt;/code&gt;, &lt;code&gt;Proxy&lt;/code&gt;, &lt;code&gt;Reflect&lt;/code&gt; and many more 😉. An enum is very useful for writing clean and readable code. Here, we've created an enum using JavaScript &lt;code&gt;Proxy&lt;/code&gt; object and prevent the enum from being modified externally. For doing that we've used Proxy's &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;get&lt;/code&gt; handler functions. And finally, we can achieve what we are expecting.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Create your own Joomla! 4 component using the JEXT-CLI application.</title>
      <dc:creator>Sajeeb Ahamed</dc:creator>
      <pubDate>Fri, 26 Mar 2021 10:18:26 +0000</pubDate>
      <link>https://dev.to/ahamed_/create-your-own-joomla-4-component-using-the-jext-cli-application-o5h</link>
      <guid>https://dev.to/ahamed_/create-your-own-joomla-4-component-using-the-jext-cli-application-o5h</guid>
      <description>&lt;p&gt;Hello, all the Joomla extension developers. Today I am going to share with you a nice CLI application for generating Joomla! 4 components. So, tie your belt, and let's start the journey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ahamed/jext-cli" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fs18955.pcdn.co%2Fwp-content%2Fuploads%2F2018%2F02%2Fgithub.png" title="jext-cli repository"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The stable version of Joomla! 4 is going to release very soon. And as it is a major release so there are some major changes that may break your existing extensions. So it would be hard for the developers to upgrade the extensions from Joomla! 3 to 4.&lt;/p&gt;

&lt;p&gt;In this statement, you may disagree with me that upgrading from 3 to 4 is not that much hard. If one already makes compatible his/her extension for &lt;code&gt;3.9.x&lt;/code&gt; then it's easy. I also agree with you. But Joomla! 4 brings a newly organized component structure for you. What if you want to taste the original flavor? You need to do more.&lt;/p&gt;

&lt;p&gt;Today, I am going to introduce you to a new CLI application. The application helps you to create a component by just running a simple command in the terminal. This will provide you a boilerplate of a structured Joomla! 4 component. &lt;/p&gt;

&lt;p&gt;By using this you can create a new component and also brings your business logic from your existing components after creating a new component (as J4 still provides you MVC structure).&lt;/p&gt;

&lt;p&gt;Here the question is how to use it? It's quite easy. Just follow me-&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For using the &lt;code&gt;jext-cli&lt;/code&gt; you need &lt;strong&gt;php-cli&lt;/strong&gt; and &lt;strong&gt;composer&lt;/strong&gt; installed in your machine. The installation is written for Linux &amp;amp; Mac users. For Windows users, this is not going to work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Clone the Github repository &lt;code&gt;git clone https://github.com/ahamed/jext-cli.git&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to the directory, &lt;code&gt;cd jext-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install the project dependencies, &lt;code&gt;composer install&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Update the autoloading classes, &lt;code&gt;composer dump-autoload -o&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Install the CLI tool, &lt;code&gt;./install.sh&lt;/code&gt; (for macOS &amp;amp; Linux)&lt;/li&gt;
&lt;li&gt;Check if the tool is installed, &lt;code&gt;jext-cli --help&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you find the manuscript that means the &lt;code&gt;jext-cli&lt;/code&gt; is installed on your machine globally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Usage
&lt;/h3&gt;

&lt;p&gt;You can create components and views for a component now. For creating a component first navigate to your Joomla! 4 project root directory, &lt;code&gt;cd path/to/your/project/root&lt;/code&gt;, then run-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;jext-cli --component|-c &amp;lt;component_name&amp;gt;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;--component|-c&lt;/code&gt; means any of &lt;code&gt;--component&lt;/code&gt; or &lt;code&gt;-c&lt;/code&gt;, and the &lt;code&gt;&amp;lt;component_name&amp;gt;&lt;/code&gt; is the name of your component. Please don't use a multi-word name as a component name.&lt;/p&gt;

&lt;p&gt;This command will ask for some basic meta-information. They are-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Author name&lt;/strong&gt; (What is the name of the component author. If skip &lt;code&gt;jext-cli&lt;/code&gt; will take the current username as author name.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Author Email&lt;/strong&gt; (The email address of the component author. If skip then it will be empty.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Author Url&lt;/strong&gt; (The author website url, If skip then it will be empty.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Description&lt;/strong&gt; (The component description. If skip then it will be empty.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copyright&lt;/strong&gt; (Copyright information, default &lt;code&gt;(C) {year}, {Author name}&lt;/code&gt;.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;License&lt;/strong&gt; (Component license information, default &lt;code&gt;MIT&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Version&lt;/strong&gt; (Component initial version number, default &lt;code&gt;1.0.0&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Namespace&lt;/strong&gt; (The component's namespace, default &lt;code&gt;Joomla\Component\&amp;lt;ComponentName&amp;gt;&lt;/code&gt;. Using the default is recommended.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Do you confirm component creation?&lt;/strong&gt; (Hit enter if everything is okay. If not then type &lt;code&gt;no&lt;/code&gt; and hit enter.)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fill them up correctly and this will create the component.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;By default, the &lt;strong&gt;JEXT-CLI&lt;/strong&gt; creates a component with two sample views. If you don't want to create the views with the component then use &lt;code&gt;--no-sample-view&lt;/code&gt; flag with it. For example-&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;jext-cli --component &amp;lt;component_name&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--no-sample-view&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you successfully created your component. Now we know all components have one or more views. The views are categorized into two types. Administrator view and site view. Here the administrator views are called &lt;code&gt;back&lt;/code&gt; views,  and the site views are called &lt;code&gt;front&lt;/code&gt; views. For creating a view, the command is-&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;jext-cli --view [--back|-b, [--front|-f, [--both|-bt]]]
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the  &lt;code&gt;[--back|-b, [--front|-f, [--both|-bt]]]&lt;/code&gt; means any of the six options. If I describe the options, then they are-&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--back|-b&lt;/code&gt; means either &lt;code&gt;--back&lt;/code&gt; or &lt;code&gt;-b&lt;/code&gt; which stands for the back view or the administrator view.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--front|-f&lt;/code&gt; means either &lt;code&gt;--front&lt;/code&gt; or &lt;code&gt;-f&lt;/code&gt; which stands for the front view or the site view.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--both|-bt&lt;/code&gt; means either &lt;code&gt;--both&lt;/code&gt; or &lt;code&gt;-bt&lt;/code&gt; stands for both administrator and site views.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After running any of the commands the application asks you the component name. This indicates for which component you are going to create a view.&lt;/p&gt;

&lt;p&gt;After putting the valid component name the system will ask you for the view's names. You have to enter two names for a view. One is the singular name and another is the plural name. The &lt;code&gt;JEXT-CLI&lt;/code&gt; can predict the plural name after you entering the singular name. If you think the prediction is correct then just hit enter otherwise, enter the plural name. That's all for creating a view. All the related (controller, model, view) files are created for you. This also injects the required language strings, SQL queries, and other required codes for making the view functional.&lt;/p&gt;

&lt;p&gt;Your view is created. You can create as many views as you need. After creating all the views log in as &lt;code&gt;administrator&lt;/code&gt; to the project then go to &lt;code&gt;Settings &amp;gt; Discover&lt;/code&gt;. There you can see the component waits for you to install. Select the component and click the &lt;code&gt;Install&lt;/code&gt; button from the toolbar.&lt;/p&gt;

&lt;p&gt;Hurra! the component has been installed. Now from the sidebar, go to &lt;code&gt;Components &amp;gt; Your component&lt;/code&gt;. Here you get your views.&lt;/p&gt;

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

&lt;p&gt;The &lt;code&gt;JEXT-CLI&lt;/code&gt; can boost up your development speed and helps you to write error prune code. If anyone is interested to contribute to the project then you are welcome. In the next versions, the &lt;code&gt;JEXT-CLI&lt;/code&gt; will try to bring the ability to create &lt;code&gt;plugins&lt;/code&gt;, and &lt;code&gt;modules&lt;/code&gt;, also provide support for Joomla! 3.&lt;/p&gt;

</description>
      <category>joomla</category>
      <category>extension</category>
      <category>phpcli</category>
      <category>jextcli</category>
    </item>
  </channel>
</rss>
