<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Abhijeet Nandvikar's Blog]]></title><description><![CDATA[Software Engineer at Procedure Technologies. I build awesome stuff for the web and have two years of experience creating web apps using JS, TS, React, Next.js, ]]></description><link>https://blogs.abhijeetnandvikar.com</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 08:17:52 GMT</lastBuildDate><atom:link href="https://blogs.abhijeetnandvikar.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to implement Notion's command feature in your web app.]]></title><description><![CDATA[Notion is a great productivity application and one of the factors that differentiate it from other similar apps in this category is its easy-to-use commands feature. This is invoked when we press the “/” key. In this article, we are going to learn ho...]]></description><link>https://blogs.abhijeetnandvikar.com/how-to-implement-notions-command-feature-in-your-web-app</link><guid isPermaLink="true">https://blogs.abhijeetnandvikar.com/how-to-implement-notions-command-feature-in-your-web-app</guid><category><![CDATA[notion]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Abhijeet Nandvikar]]></dc:creator><pubDate>Tue, 16 May 2023 05:36:46 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1682172392820/fc1080cf-c801-42a1-bfa0-3cbb112fc100.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Notion is a great productivity application and one of the factors that differentiate it from other similar apps in this category is its easy-to-use commands feature. This is invoked when we press the “/” key. In this article, we are going to learn how to create this interaction for our note editor. We will use the slate.js library for this. This is an attempt to explain the functionality in the easiest way possible. Now let’s get started…</p>
<h3 id="heading-what-is-slate"><strong>What is Slate?</strong></h3>
<p>Slate is a <em>completely</em> customizable framework for building rich text editors. It can do this because all of its logic is implemented with a series of plugins, so you aren't ever constrained by what <em>is</em> or <em>isn't</em> in the "core". You can think of it as a pluggable implementation of contenteditable built on top of React - (Taken from slate.js documentation). You can learn more about it here. <a target="_blank" href="https://docs.slatejs.org/">https://docs.slatejs.org/</a>.</p>
<p><strong>Overall I have divided this article into the following sections:</strong></p>
<ol>
<li><p>Getting started with slate.js</p>
</li>
<li><p>Understanding the required Concepts</p>
</li>
<li><p>Implementation</p>
</li>
</ol>
<h3 id="heading-getting-started">Getting started.</h3>
<p>Let's initialize our web app with <code>create-react-app</code>, and name it <code>notion-clone</code>.</p>
<pre><code class="lang-plaintext">npx install create-react-app notion-clone
</code></pre>
<p>Install the required packages.</p>
<pre><code class="lang-plaintext">yarn add slate slate-react
</code></pre>
<p>Create a TextEditor component, import all the required components, and that’s it, now you have a basic working project. <a target="_blank" href="https://notion-slatejs-demo.netlify.app/basic-demo">click here to check how it will look.</a></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;
<span class="hljs-keyword">import</span> { createEditor } <span class="hljs-keyword">from</span> <span class="hljs-string">"slate"</span>;
<span class="hljs-keyword">import</span> { Slate, Editable } <span class="hljs-keyword">from</span> <span class="hljs-string">"slate-react"</span>;

<span class="hljs-keyword">const</span> initialValue = [
  {
    <span class="hljs-keyword">type</span>: <span class="hljs-string">'paragraph'</span>,
    children: [{ text: <span class="hljs-string">'A line of text in a paragraph.'</span> }],
  },
]

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-comment">// createEditor function will return an Editor object, and withReact function will add react specific behaviour to the editor.</span>
  <span class="hljs-comment">// We will store it inside a state variable called editor</span>
  <span class="hljs-keyword">const</span> [editor] = useState(<span class="hljs-function">() =&gt;</span> withReact(createEditor()))
  <span class="hljs-keyword">return</span> (
      <span class="hljs-comment">/* Slate component provides the editor context to it's children.
      Editable component renders the text editor where we can write
      and edit stuff */</span>
    &lt;Slate editor={editor} value={initialValue}&gt;
      &lt;Editable /&gt;
    &lt;/Slate&gt;
  )
}
</code></pre>
<h3 id="heading-understanding-the-required-concepts">Understanding the required concepts</h3>
<p>Slate.js is a highly customizable rich text editor. Whatever we type inside our note component (let’s call this note data also called descendants) will be stored as an array of objects and is rendered on the screen in the form of HTML elements. We will discuss its structure and how to customize it in the later parts.</p>
<h3 id="heading-nodes">Nodes:</h3>
<p>Nodes are of 3 types:</p>
<ul>
<li><p><strong>The root-level Editor node:</strong></p>
<p>  This is the top-most level of the node, all the note data can be accessed inside the children property of this node. It contains a bunch of useful methods and properties, we will discuss this in a later section. The Editor node consists of multiple Element nodes.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">interface</span> Editor {
      children : Node[]
      selection : Range | <span class="hljs-literal">null</span>
      <span class="hljs-comment">// ...more properties and helper functions</span>
  }
</code></pre>
</li>
<li><p><strong>The element level Element node:</strong></p>
<p>  Elements are present in the middle layer of the document and we can customize it as per our needs. Element node consists of multiple text nodes.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">interface</span> Element {
      children : Node[]
      <span class="hljs-keyword">type</span> : <span class="hljs-string">'heading-one'</span>
      <span class="hljs-comment">// ...we can add more custom properties here, similar to type</span>
  }
</code></pre>
</li>
<li><p><strong>The Text level Text Node:</strong></p>
<p>  Text nodes are the lowest-level nodes in the tree, containing the text content of the document, along with any formatting.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">interface</span> Text {
    text : <span class="hljs-built_in">string</span>
    bold : <span class="hljs-literal">true</span>
    <span class="hljs-comment">// ...we can add more custom properties here, similar to bold</span>
  }
</code></pre>
</li>
</ul>
<p>These Nodes combine together to form an editor document.</p>
<h3 id="heading-locations">Locations:</h3>
<p>Locations are used to refer to a specific node or a point in the document while performing various operations like selection, insertion, updation, deletion, etc.</p>
<p>There are 3 ways to refer to a location.</p>
<ul>
<li><p><strong>Path:</strong> This is just an array of numbers used to point at a specific element node.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">type</span> Path = <span class="hljs-built_in">number</span>[]
</code></pre>
</li>
<li><p><strong>Point:</strong> This is a combination of path and offset that can be used to locate any point in a node. It can be used to specify the exact location of the cursor inside the editor.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">interface</span> Point {
    path: Path
    offset: <span class="hljs-built_in">number</span>
  }
</code></pre>
</li>
<li><p><strong>Range:</strong> This can be used to specify a range of a selection between two point locations.</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">interface</span> Range {
    anchor: Point
    focus: Point
  }
</code></pre>
</li>
</ul>
<h3 id="heading-rendering">Rendering:</h3>
<p>Internally note data is stored as an array of objects also called nodes. We can define a custom render function to render these objects in the required way. We need to pass this to the Editable component.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> renderElement = <span class="hljs-function">(<span class="hljs-params">{attributes,children,<span class="hljs-keyword">type</span>}</span>) =&gt;</span> {
    <span class="hljs-keyword">switch</span> (<span class="hljs-keyword">type</span>) {
      <span class="hljs-keyword">case</span> <span class="hljs-string">'heading-one'</span>:
        <span class="hljs-keyword">return</span> &lt;h1 {...attribututes}&gt;{children}&lt;/h1&gt;
      <span class="hljs-keyword">default</span>:
        <span class="hljs-keyword">return</span> &lt;p {...attributes}&gt;{children}&lt;/p&gt;
    }

<span class="hljs-comment">// This is passed to the Editable component</span>
&lt;Editable renderElement={renderElement} /&gt;
</code></pre>
<h3 id="heading-transforms">Transforms:</h3>
<p>Transforms are set of operations like update, delete, insert, move, etc. that you can apply to single or multiple sets of nodes.</p>
<blockquote>
<p>Slate has an immutable data structure, which means you cannot directly change its data. Instead, we use transform operations to change its data.</p>
</blockquote>
<pre><code class="lang-typescript"><span class="hljs-comment">// Examples</span>

Transforms.select(editor, {
  anchor: { path: [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>], offset: <span class="hljs-number">0</span> },
  focus: { path: [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>], offset: <span class="hljs-number">2</span> },
}) <span class="hljs-comment">// this will select the text in given range</span>

Transforms.delete(editor, {
  at: {
    anchor: { path: [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>], offset: <span class="hljs-number">0</span> },
    focus: { path: [<span class="hljs-number">1</span>, <span class="hljs-number">0</span>], offset: <span class="hljs-number">2</span> },
  },
}) <span class="hljs-comment">// this will delete text in given range</span>
</code></pre>
<h3 id="heading-implementation">Implementation</h3>
<p>Now that we have a basic understanding of the required concepts, we can start with the implementation of our functionality. Let's look at the steps involved...</p>
<ol>
<li><p><strong>Declare a list of commands.</strong></p>
<p> This is the list of commands we want to invoke after pressing the "/" key.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> commandOptions = [
   <span class="hljs-string">"heading-one"</span>,
   <span class="hljs-string">"heading-two"</span>,
   <span class="hljs-string">"code-block"</span>,
   <span class="hljs-comment">// ...other commands if required</span>
 ];
</code></pre>
</li>
<li><p><strong>Declare custom elements that need to be rendered once a command is invoked.</strong></p>
<p> In this step, we declare how each command option will be rendered on the page, eg. heading-one, code-block, etc.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> HeadingOneBlock = <span class="hljs-function">(<span class="hljs-params">{ attributes, children }</span>) =&gt;</span> {
   <span class="hljs-keyword">return</span> &lt;h1 {...attributes}&gt;{children}&lt;/h1&gt;;
 };

 <span class="hljs-keyword">const</span> HeadingTwoBlock = <span class="hljs-function">(<span class="hljs-params">{attributes,children}</span>) =&gt;</span> {
    <span class="hljs-keyword">return</span> &lt;h2 {...attributes}&gt;{children}&lt;/h2&gt;;
 }

 <span class="hljs-comment">// similarly we can declare complex functionality eg, a component to render a code block or images, etc.</span>
</code></pre>
</li>
<li><p><strong>Create a function to render custom elements.</strong></p>
<p> Here we are writing a function that will render the custom elements depending on the node type.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> renderElement = <span class="hljs-function">(<span class="hljs-params">{attributes,children,<span class="hljs-keyword">type</span>}</span>) =&gt;</span> {
     <span class="hljs-keyword">switch</span> (<span class="hljs-keyword">type</span>) {
       <span class="hljs-keyword">case</span> <span class="hljs-string">'heading-one'</span>:
         <span class="hljs-keyword">return</span> &lt;HeadingOneBlock attributes={attribututes}&gt;{children}&lt;/HeadingOneBlock&gt;
       <span class="hljs-comment">// ...more components</span>
       <span class="hljs-keyword">default</span>:
         <span class="hljs-keyword">return</span> &lt;p {...attributes}&gt;{children}&lt;/p&gt;
  }
</code></pre>
</li>
<li><p><strong>Create a portal.</strong></p>
<p> React Portal provides a way to render a component to dom nodes present outside react component tree. In our case, we want to show a list of commands when we press "/", and these options should float exactly where our cursor is present. The reason we will be using this is that It should not be affected by any CSS styles written for its parent component.</p>
<p> Here "RenderCommandList" component takes the command list and renders it on the screen. We will also create a "ref" and pass it to "RenderCommandList". We will discuss its use in later parts.</p>
<pre><code class="lang-typescript"> <span class="hljs-comment">// Whatever we pass as children will be attached to document body</span>
 <span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Portal = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {
   <span class="hljs-keyword">return</span> <span class="hljs-keyword">typeof</span> <span class="hljs-built_in">document</span> === <span class="hljs-string">"object"</span>
     ? ReactDOM.createPortal(children, <span class="hljs-built_in">document</span>.body)
     : <span class="hljs-literal">null</span>;
 };
 ​
 <span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-comment">// ...some code</span>
   <span class="hljs-comment">// We will pass this refrence to RenderCommandList so that we can handle its position later according to cursor placement.</span>
   <span class="hljs-keyword">const</span> ref = useRef(); 
   <span class="hljs-comment">// We will show/hide command options when we press "/" key.</span>
   <span class="hljs-keyword">const</span> [showCommandMenu, setShowcommandMenu] = useState(<span class="hljs-literal">false</span>);
 ​
   <span class="hljs-keyword">return</span> (
     &lt;div&gt;
       &lt;Slate editor={editor} value={initialValue}&gt;
         &lt;Editable renderElement={renderElement}/&gt;
         {showCommandMenu &amp;&amp; (
           &lt;Portal&gt;
             &lt;RenderCommandList refrence={ref} /&gt;
           &lt;/Portal&gt;
         )}
       &lt;/Slate&gt;
     &lt;/div&gt;
   );
 };
</code></pre>
</li>
<li><p><strong>Add a key-down event handler.</strong></p>
<p> In this step, we will declare a function "onKeyDownHandler" and will pass it to the Editable component. Whenever any key is pressed this function will be called and we can execute the required functionality. In the below code block once this function is invoked</p>
<ol>
<li><p>we are checking if the "/" key is pressed. If true, the "showCommand" state is set to true, and the "commandMode" state is set to true as well.</p>
</li>
<li><p>If "ArrowUp" or "ArrowDown" is pressed we update the selected "commandIndex".</p>
</li>
<li><p>On pressing enter, the "executeCommand" function is called and the required functionality is executed. We will discuss this function in the later part.</p>
</li>
</ol>
</li>
</ol>
<pre><code class="lang-typescript">    <span class="hljs-keyword">const</span> [commandIndex, setCommandIndex] = useState(<span class="hljs-number">0</span>);
    <span class="hljs-keyword">const</span> [commandMode, setCommandMode] = useState(<span class="hljs-literal">false</span>);
    ​
    <span class="hljs-keyword">const</span> onKeyDownHandler = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
        <span class="hljs-keyword">if</span> (event.key === <span class="hljs-string">"/"</span>) {
          setShowcommandMenu(<span class="hljs-literal">true</span>);
          setCommandMode(<span class="hljs-literal">true</span>);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (commandMode &amp;&amp; event.key === <span class="hljs-string">"ArrowDown"</span>)                 {
          event.preventDefault();
          setCommandIndex(commandIndex + <span class="hljs-number">1</span>);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (commandMode &amp;&amp; event.key === <span class="hljs-string">"ArrowUp"</span>) {
          event.preventDefault();
          setCommandIndex(commandIndex - <span class="hljs-number">1</span>);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (commandMode &amp;&amp; event.key === <span class="hljs-string">"Enter"</span>) {
          event.preventDefault();
          setShowcommandMenu(<span class="hljs-literal">false</span>);
          setCommandMode(<span class="hljs-literal">false</span>);
          executeCommand(event);
        }
      };
    ​
    <span class="hljs-comment">// Pass it to Editable component</span>
    &lt;Editable renderElement={renderElement} onKeyDown=
        {onKeyDownHandler}/&gt;
</code></pre>
<ol>
<li><p><strong>Add editor change handler.</strong></p>
<p> Now we will create an "editorChangeHandler" function and pass it to the Slate component. This will be called when editor data changes. Inside this function when the "commandMode" is active, we update our "target" state. In this state, we store the location of our current selection or cursor location in terms of Slate Range. "target" state will be used for determining at what location to render our command options later.</p>
<pre><code class="lang-typescript"> <span class="hljs-keyword">const</span> editorChangeHandler = <span class="hljs-function">(<span class="hljs-params">value</span>) =&gt;</span> {
       <span class="hljs-keyword">const</span> { selection, children } = editor;
       <span class="hljs-keyword">if</span> (commandMode) {
         <span class="hljs-keyword">const</span> currentNode = Node.get(editor, selection.anchor.path);
         setTarget(selection);
       }
     };

 <span class="hljs-comment">// Pass it to Slate component</span>
 &lt;Slate editor={editor} value={initialValue} onChange=
     {editorChangeHandler}&gt;
</code></pre>
</li>
<li><p><strong>Add execute command function.</strong></p>
<p> Remember we called the "executeCommand" function in the 5th step? Here we just check the "commandIndex" and get the selected command. Then we apply the correct transforms to update the note data as required.</p>
<blockquote>
<p>Slate has an immutable data structure, which means you cannot directly change its data. Instead, we use transform operations to do this.</p>
</blockquote>
<p> As per the code written below, if the current selected command is "heading-one", we do two things</p>
<ol>
<li><p>Apply deleteBackward transform to remove "/".</p>
</li>
<li><p>Update the currentNode by changing its type to "heading-one". Inside the "children" property, we can specify text inside the "heading-one". In the "at" property we specify the location at which the current transform needs to be applied</p>
</li>
</ol>
</li>
</ol>
<pre><code class="lang-typescript">    <span class="hljs-keyword">const</span> executeCommand = <span class="hljs-function">(<span class="hljs-params">event</span>) =&gt;</span> {
      <span class="hljs-keyword">switch</span> (commandOptions[commandIndex]) {
          <span class="hljs-keyword">case</span> <span class="hljs-string">"heading-one"</span>: {
              Editor.deleteBackward(editor, { unit: <span class="hljs-string">"character"</span> });
              Transforms.setNodes(editor, {
                <span class="hljs-keyword">type</span>: <span class="hljs-string">"heading-one"</span>,
                children: [{ text: <span class="hljs-string">""</span> }],
                at: editor.selection,
              });
              <span class="hljs-keyword">break</span>;
            }
          <span class="hljs-comment">// ...more functionality</span>
          <span class="hljs-keyword">default</span>: {
              event.preventDefault();
            }
          }
        };
</code></pre>
<ol>
<li><p><strong>Add useEffect for calculating the portal position.</strong></p>
<p> Here, if the editor data is selected command or cursor position changes we execute the following code. It performs the following actions...</p>
<ol>
<li><p>First, we check if we have the current selection location in the "target" state.</p>
</li>
<li><p>Remember the reference passed to the "RenderCommandList" component mentioned in the above code? we get that and store it in a const named "popUpRef".</p>
</li>
<li><p>"ReactEditor.toDOMRange" gives us the native dom Range from the Slate dom range.</p>
</li>
<li><p>The domRange.getBoundingClientRect() method returns an <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/DOMRect"><code>DOMRect</code></a> object providing information about the size of an element and its position relative to the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Glossary/Viewport">viewport</a>.</p>
</li>
<li><p>Finally set the position for the "RenderCommandList" using this data.</p>
<pre><code class="lang-typescript"> useEffect(<span class="hljs-function">() =&gt;</span> {
     <span class="hljs-keyword">if</span> (target) {
       <span class="hljs-keyword">const</span> popUpRef = ref.current;
       <span class="hljs-keyword">const</span> domRange = ReactEditor.toDOMRange(editor, target);
       <span class="hljs-keyword">const</span> rect = domRange.getBoundingClientRect();
       popUpRef.style.top = <span class="hljs-string">`<span class="hljs-subst">${rect.top + <span class="hljs-number">24</span>}</span>px`</span>;
       popUpRef.style.left = <span class="hljs-string">`<span class="hljs-subst">${rect.left}</span>px`</span>;
     }
   }, [ editor, commandIndex, target]);
</code></pre>
<p> And that's it we have our command functionality working.</p>
</li>
</ol>
</li>
</ol>
<p><strong>That's it! Our implementation is complete...</strong></p>
<p>Here is a full working demo of what we have implemented- <a target="_blank" href="https://notion-slatejs-demo.netlify.app/clinical-codes-example">Link</a></p>
<p>Here is the Github link for its code - <a target="_blank" href="https://github.com/AbhijeetNandvikar/slate-js-demo">Link</a></p>
<p>To learn more about slate.js, check out the official docs - <a target="_blank" href="https://docs.slatejs.org/">Link</a></p>
<p>I hope you find this blog useful, let me know if you have any questions or suggestions. Feel free to DM me on Twitter - <a target="_blank" href="https://twitter.com/AbhiNandvikar">Link</a>.</p>
<p>Have a great day!</p>
]]></content:encoded></item><item><title><![CDATA[Objects in javascript]]></title><description><![CDATA[In this blog, I will try to cover the concept of objects in JavaScript in detail. After reading this blog I am sure you will have a clear understanding of the topic. Let's get started…
Introduction.
Object in JavaScript is just a collection of key-va...]]></description><link>https://blogs.abhijeetnandvikar.com/objects-in-javascript</link><guid isPermaLink="true">https://blogs.abhijeetnandvikar.com/objects-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Objects]]></category><category><![CDATA[HTML5]]></category><category><![CDATA[vanilla-js]]></category><category><![CDATA[ES6]]></category><dc:creator><![CDATA[Abhijeet Nandvikar]]></dc:creator><pubDate>Sun, 23 Apr 2023 18:22:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1682274330257/157cde63-92e4-4658-abea-54eeca93bf91.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, I will try to cover the concept of objects in JavaScript in detail. After reading this blog I am sure you will have a clear understanding of the topic. Let's get started…</p>
<h2 id="heading-introduction"><strong>Introduction.</strong></h2>
<p>Object in JavaScript is just a collection of key-value pairs. A key can be considered as a unique name for every value so that we can access them. Values can be either a primitive data type or they can be a function or another object. These key-value pairs are called properties or methods depending on the type of value.</p>
<p>Let’s take an example :</p>
<p>Here a person is an object. It has two properties called name, and age and one method called greets. Here "name", "age" and "greets" belongs to the person object and we can access them in the following way.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> person = {
    <span class="hljs-attr">name</span> : <span class="hljs-string">"Rahul"</span>,
    <span class="hljs-attr">age</span> : <span class="hljs-number">20</span> ,
    <span class="hljs-attr">greets</span> : <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>)</span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hi, I am Rahul"</span>)
    }
}

<span class="hljs-comment">// Accessing the object</span>
<span class="hljs-built_in">console</span>.log(person.name)  <span class="hljs-comment">//Output : "Rahul"</span>
<span class="hljs-built_in">console</span>.log(person.age)   <span class="hljs-comment">//Output : 20</span>
<span class="hljs-built_in">console</span>.log(person.greets())    <span class="hljs-comment">//Output : "Hi, I am Rahul"</span>
</code></pre>
<p>We can also access objects using square bracket notation</p>
<pre><code class="lang-javascript">
<span class="hljs-comment">// Accessing the object using square bracket notation</span>
<span class="hljs-built_in">console</span>.log(person.[<span class="hljs-string">'name'</span>])  <span class="hljs-comment">//Output : "Rahul"</span>
<span class="hljs-built_in">console</span>.log(person.[<span class="hljs-string">'age'</span>])   <span class="hljs-comment">//Output : 20</span>
<span class="hljs-built_in">console</span>.log(person.[<span class="hljs-string">'greets'</span>]())    <span class="hljs-comment">//Output : "Hi, I am Rahul"</span>
</code></pre>
<blockquote>
<p><em>Note : Square bracket notation is used in case we want to access properties dynamically</em></p>
</blockquote>
<h2 id="heading-creating-objects-in-javascript"><strong>Creating objects in javaScript</strong></h2>
<p>There are various methods of creating an object but we will focus on the following three :</p>
<h3 id="heading-direct-method"><strong>Direct method:</strong></h3>
<p>We have seen this in the above example</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> person = {
    <span class="hljs-attr">name</span> : <span class="hljs-string">"Rahul"</span>,
    <span class="hljs-attr">age</span> : <span class="hljs-number">20</span> ,
    <span class="hljs-attr">greets</span> : <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>)</span>{
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hi, I am Rahul"</span>)
    }
}

<span class="hljs-built_in">console</span>.log(typeOf(person))

<span class="hljs-comment">//Output : Object</span>
</code></pre>
<h3 id="heading-using-a-function-constructor"><strong>Using a function constructor :</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Animal</span>(<span class="hljs-params">name,type,voice</span>)</span>{
<span class="hljs-keyword">const</span> color = <span class="hljs-string">"something"</span> ;
<span class="hljs-built_in">this</span>.name = name ;
<span class="hljs-built_in">this</span>.type = type ;
<span class="hljs-built_in">this</span>.sound = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(voice) ;
  }
}

<span class="hljs-comment">// Creating an Object using constructor function</span>
<span class="hljs-keyword">const</span> Tiger = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Tiger'</span>,<span class="hljs-string">'mammal'</span>,<span class="hljs-string">'roar...'</span>)

<span class="hljs-built_in">console</span>.log(Tiger)  <span class="hljs-comment">//Output : Animal {name: "Tiger", type: "mammal", sound: ƒ}</span>

<span class="hljs-built_in">console</span>.log(Tiger.sound()) <span class="hljs-comment">//Output : roar...</span>
</code></pre>
<p>This is a dynamic way of creating JavaScript objects.</p>
<p>Animal() is just a simple js function that acts as a constructor for the Tiger object. Notice how the "this" keyword is used here, it is used to create properties and methods for the Tiger object.</p>
<p>The "new" keyword creates an empty object. "this" keyword in the Animal function references that empty object.</p>
<p>If we simply declare some variable in Animal() our code will not throw any error, but that variable will not become a property of the object.</p>
<p>For eg. in our case observe that colour is not a property of the Tiger object.</p>
<blockquote>
<p><em>Arrow functions can’t be used as a function constructor</em></p>
<p><em>Always the first letter of the function constructor name should be capitalised according to the convention</em></p>
<p><em>The Arguments in Animal function can be used to pass values to objects dynamically.</em></p>
<p><em>This is a dynamic way of creating an object in js.</em></p>
</blockquote>
<h3 id="heading-using-es6-class-concept"><strong>Using ES6 class concept:</strong></h3>
<pre><code class="lang-javascript"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span> </span>{
  <span class="hljs-keyword">constructor</span>(name,type,voice){
    <span class="hljs-built_in">this</span>.name = name ;
       <span class="hljs-built_in">this</span>.type = type ;
    <span class="hljs-built_in">this</span>.sound = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(voice) ;
    }
  }
}

<span class="hljs-comment">// Let's create an object using Animal class</span>
<span class="hljs-keyword">const</span> Tiger = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Tiger'</span>,<span class="hljs-string">'mammal'</span>,<span class="hljs-string">'roar...'</span>)

<span class="hljs-built_in">console</span>.log(Tiger) <span class="hljs-comment">//Output : Animal {name: "Tiger", type: "mammal", sound: ƒ}</span>
<span class="hljs-built_in">console</span>.log(Tiger.sound()) <span class="hljs-comment">// Output : roar...</span>
</code></pre>
<p>Here we are creating a class named "Animal". All the properties and methods which we want to assign to the object are placed inside the class constructor.</p>
<p>The constructor receives arguments that we have passed while object creation.</p>
<p>A JavaScript class is declared with a PascalCase in contrast to other JavaScript data structures ie. the first letter in every word should be capitalized. Eg; class "AnimalKingdom"</p>
<blockquote>
<p><em>Make sure you use you call super() method inside the constructor() method if the current object extends some other object, this is done so that we can use properties and method of the parent class.</em></p>
</blockquote>
<h3 id="heading-the-mutability-of-objects-in-javascript">The mutability of objects in javascript</h3>
<p>Primitive data types like number, boolean, and string are Immutable whereas objects in js are mutable in nature. Mutability means that we can edit the values after it is assigned. Let’s look at a simple example that will make things clear.</p>
<pre><code class="lang-javascript">
<span class="hljs-keyword">let</span> name1 = <span class="hljs-string">'Rahul'</span> ;
<span class="hljs-keyword">let</span> name2 = name1 ;
name2 = <span class="hljs-string">'Ramesh'</span>
<span class="hljs-built_in">console</span>.log(name1)  <span class="hljs-comment">//Output : Rahul</span>
<span class="hljs-built_in">console</span>.log(name2)  <span class="hljs-comment">//Output : Rahul</span>
</code></pre>
<p>In the above code snippet variable name1 contains the string - "Rahul"</p>
<p>On the second line we are saying that assign value in name1 to name2. So here the value gets copied and if we change variable name2 then, name1 doesn’t get affected.</p>
<p>which is obvious</p>
<p>but objects don't exhibit such behavior,</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> person1 = {
    <span class="hljs-attr">name</span> : <span class="hljs-string">'Rahul'</span> 
}

<span class="hljs-keyword">let</span> person2 = person1 ;

<span class="hljs-comment">// updating person2</span>
person2.name = <span class="hljs-string">"Ramesh"</span>

<span class="hljs-built_in">console</span>.log(person1) <span class="hljs-comment">// Output : {name: "Ramesh"}</span>
<span class="hljs-built_in">console</span>.log(person2)    <span class="hljs-comment">// Output : {name: "Ramesh"}</span>

<span class="hljs-comment">// Why do this happen?</span>
</code></pre>
<p>In the case of objects, the person1 variable holds the address to the memory location where the object data is stored and when we assign person1 to person2 this address gets copied into the person2 variable.</p>
<p>Therefore now making changes in a person2 will also affect person1 object.</p>
<p>Let's take one more example :</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> person1 = {
    <span class="hljs-attr">name</span> : <span class="hljs-string">'Rahul'</span> 
}
<span class="hljs-keyword">let</span> person2 = person1 ;

<span class="hljs-comment">// Case 1</span>
<span class="hljs-keyword">if</span>(person1 ===  person2){
  <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">true</span>)
}
<span class="hljs-keyword">else</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">false</span>)
}



<span class="hljs-keyword">let</span> person3 = {
  <span class="hljs-attr">name</span> : <span class="hljs-string">'Rahul'</span>
}
<span class="hljs-keyword">let</span> person4 = {
  <span class="hljs-attr">name</span> : <span class="hljs-string">'Rahul'</span>
}
<span class="hljs-comment">// Case 2</span>
<span class="hljs-keyword">if</span>(person3 ===  person4){
  <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">true</span>)
}
<span class="hljs-keyword">else</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">false</span>)
}
</code></pre>
<p>In case 1 answer will be true because both variables contain the same address and on the comparison, the answer will be true.</p>
<p>On the other hand case 2 output will be false. This is because even though person3 and person4 have the same content inside they are stored in different memory location and the above two variable only contains their addresses.</p>
<p>Now you must be wondering how to compare two objects. How to find whether objects received from two different sources have the same properties and methods?</p>
<p>Actually, there is no direct way because the variable stores the address to the memory locations and the content inside that memory location is not evaluated,</p>
<p>But don’t worry there is one hack though…</p>
<p>We can Convert the objects which we want to compare into string format using JSON.stringify() method. Store those values and compare them using the equality operator. And now the output will be true</p>
<pre><code class="lang-javascript">
<span class="hljs-keyword">const</span> k1 = { <span class="hljs-attr">fruit</span>: <span class="hljs-string">'Kiwi'</span> };
<span class="hljs-keyword">const</span> k2 = { <span class="hljs-attr">fruit</span>: <span class="hljs-string">'kiwi'</span> };

<span class="hljs-comment">// Using JavaScript</span>
<span class="hljs-keyword">if</span>(<span class="hljs-built_in">JSON</span>.stringify(k1) === <span class="hljs-built_in">JSON</span>.stringify(k2)){
  <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">true</span>) ;
}
<span class="hljs-keyword">else</span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-literal">false</span>) ;
}
<span class="hljs-comment">// Output : True</span>
</code></pre>
<h3 id="heading-working-with-objects"><strong>Working with objects:</strong></h3>
<p>Here are some of the methods which can be useful while working with objects...</p>
<ul>
<li><p><strong>Object.create()</strong>: This method creates a new object, using an existing object as the blueprint.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> person = {
    <span class="hljs-attr">isHuman</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">printIntroduction</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`My name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>.`</span>);
    }
  };

  <span class="hljs-keyword">const</span> me = <span class="hljs-built_in">Object</span>.create(person);

  me.name = <span class="hljs-string">'Rahul'</span>; <span class="hljs-comment">// "name" is a property set on "me", but not on "person"</span>
  me.isHuman = <span class="hljs-literal">true</span>; <span class="hljs-comment">// inherited properties can be overwritten</span>

  me.printIntroduction();
</code></pre>
</li>
<li><p><strong>Object.keys()</strong>: This method returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> object1 = {
    <span class="hljs-attr">a</span>: <span class="hljs-string">'somestring'</span>,
    <span class="hljs-attr">b</span>: <span class="hljs-number">42</span>,
    <span class="hljs-attr">c</span>: <span class="hljs-literal">false</span>
  };

  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">Object</span>.keys(object1));
  <span class="hljs-comment">// expected output: Array ["a", "b", "c"]</span>
</code></pre>
</li>
<li><p><strong>Object.assign()</strong>: This method copies all enumerable own properties from one or more source objects to a target object. It returns the target object.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> target = { <span class="hljs-attr">a</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">2</span> };
  <span class="hljs-keyword">const</span> source = { <span class="hljs-attr">b</span>: <span class="hljs-number">4</span>, <span class="hljs-attr">c</span>: <span class="hljs-number">5</span> };

  <span class="hljs-comment">//there can be multiple sources</span>
  <span class="hljs-keyword">const</span> returnedTarget = <span class="hljs-built_in">Object</span>.assign(target, source);

  <span class="hljs-built_in">console</span>.log(target);
  <span class="hljs-comment">// expected output: Object { a: 1, b: 4, c: 5 }</span>

  <span class="hljs-built_in">console</span>.log(returnedTarget);
  <span class="hljs-comment">// expected output: Object { a: 1, b: 4, c: 5 }</span>
</code></pre>
</li>
<li><p><strong>Object.freeze():</strong> This method freezes an object. A frozen object can no longer be changed; freezing an object prevents new properties from being added to it, and existing properties from being removed, prevents changing the enumerability, configurability, or writability of existing properties and prevents the values of existing properties from being changed. In addition, freezing an object also prevents its prototype from being changed. freeze() returns the same object that was passed in.</p>
</li>
<li><p><strong>Object.seal()</strong>: This method seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">let</span> person = {
      <span class="hljs-attr">name</span> : <span class="hljs-string">"Rahul"</span>,
      <span class="hljs-attr">age</span> : <span class="hljs-number">20</span> ,
      <span class="hljs-attr">greets</span> : <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>)</span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Hi, I am Rahul"</span>)
      }
  }

  <span class="hljs-built_in">Object</span>.seal(person) ;  <span class="hljs-comment">// seals the object</span>
  <span class="hljs-built_in">Object</span>.freeze(person) ; <span class="hljs-comment">// freezes the object</span>
</code></pre>
<p>  I hope you find this blog useful, let me know if you have any questions or suggestions. Feel free to DM me on Twitter - <a target="_blank" href="https://twitter.com/AbhiNandvikar">Link</a>.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How to publish your own React component library to npm]]></title><description><![CDATA[Publishing your own react component library is actually simple than you think. In this blog, I'll show you how to do it in the simplest way possible.
Now Let's get started...

Prerequisite:

You should have an account on npmjs.com, if you don't have ...]]></description><link>https://blogs.abhijeetnandvikar.com/how-to-publish-your-own-react-component-library-to-npm</link><guid isPermaLink="true">https://blogs.abhijeetnandvikar.com/how-to-publish-your-own-react-component-library-to-npm</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[npm]]></category><category><![CDATA[package]]></category><category><![CDATA[library]]></category><dc:creator><![CDATA[Abhijeet Nandvikar]]></dc:creator><pubDate>Sun, 30 May 2021 18:16:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1622398423857/gcpPybkEg.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Publishing your own react component library is actually simple than you think. In this blog, I'll show you how to do it in the simplest way possible.</p>
<p>Now Let's get started...</p>
<blockquote>
<h4 id="prerequisite">Prerequisite:</h4>
<ol>
<li>You should have an account on npmjs.com, if you don't have it go ahead and create one. <a target="_blank" href="https://www.npmjs.com">npmjs.com</a></li>
<li>Make sure you have node version &gt;= 10 installed on your system.</li>
</ol>
</blockquote>
<p>There are many ways to get started but here we are going to use create-react-library. Using this package Rollup.js, Babel, and other configurations are handled automatically for us.</p>
<h3 id="step-1">Step 1:</h3>
<pre><code class="lang-javascript">npx create-react-library &lt;package-name&gt;
</code></pre>
<h3 id="step-2">Step 2:</h3>
<p>Enter all the details related to this package like </p>
<ol>
<li>Package name</li>
<li>Package description</li>
<li>Author's GitHub Handle</li>
<li>Github repo path</li>
<li>Select License</li>
<li>Package Manager - (npm or yarn)</li>
<li>Template</li>
</ol>
<blockquote>
<p>Note: When a user creates a user or organization account, they are granted a scope that matches the user/organization name. The scope is useful in the following scenario.</p>
<ol>
<li>When you want to create a package with the same name as a package created by another user or organization without conflict. 
Eg.  with scope:  <code>@username/xyz-app</code>, without scope: <code>xyz-app</code>.  <a target="_blank" href="https://docs.npmjs.com/about-scopes">read more</a> </li>
<li>When you want to logically group certain packages.</li>
</ol>
</blockquote>
<p>There are three options available for the templates:</p>
<ul>
<li>Default: Use this option if you want to create the package in javascript.</li>
<li>Typescript: Use this option if you want to create the package in typescript.</li>
<li>Custom: Use this option if you want to use a custom template.</li>
</ul>
<h3 id="step-3">Step 3:</h3>
<p>Now let's start the development of our package.</p>
<p>This will be the folder structure available to us.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1622385590657/3QMIsqNf_.png" alt="folderStructure.png" /></p>
<p>Local development can be separated into two parts.</p>
<ol>
<li><strong>src/</strong> folder will contain code for react package that we are creating.</li>
<li><strong>example/</strong> will contain code for a demo application where we can test our react package</li>
</ol>
<p>First, we will start rollup, this will help us to automatically recompile our package to the <strong>dist/</strong> folder.</p>
<blockquote>
<p>Note: Rollup is a module bundler for JavaScript which compiles small pieces of code into something larger and more complex, such as a library or application</p>
</blockquote>
<pre><code>npm <span class="hljs-keyword">start</span>
</code></pre><p>Next, we will navigate to <strong>example/</strong> and start the demo application. Here we will be able to import the package present in <strong>src/</strong> and test it here.</p>
<pre><code>cd example
npm <span class="hljs-keyword">start</span>
</code></pre><h3 id="step-4">Step 4:</h3>
<p>Start development of the package. Now, anytime you make a change to your library in <strong>src/</strong> or to the example app's <strong>example/src</strong>, create-react-app will live-reload your local dev server so you can iterate on your component in real-time.</p>
<blockquote>
<p>Note: Make sure that any npm modules you want as peer dependencies are properly marked as peer dependencies in package.json. The rollup config will automatically recognize them as peers and not try to bundle them in your module.</p>
</blockquote>
<h3 id="step-5">Step 5:</h3>
<p>Run <strong>npm login</strong> command and enter your credentials to log in.</p>
<pre><code>npm <span class="hljs-keyword">login</span>
</code></pre><h3 id="step-6">Step 6:</h3>
<p>This is the final step. If you are publishing a package privately you can directly run the<br />following command.</p>
<pre><code><span class="hljs-built_in">npm</span> publish
</code></pre><p>But if you are creating a public package there are few things that you can keep in mind.</p>
<ol>
<li>Have easy-to-understand documentation that explains steps for installation, getting started, configuration, and other necessary stuff required while development.</li>
<li>Share the link for a working demo of your package.</li>
<li>Add instructions about how other developers can contribute to this package.</li>
</ol>
<p>Here is one way you can showcase a working demo. Just push all the changes to GitHub and run the following command.</p>
<pre><code><span class="hljs-built_in">npm</span> run deploy
</code></pre><p>This will publish our example app to Github pages.</p>
<p>Finally,  run this command.</p>
<pre><code><span class="hljs-built_in">npm</span> publish
</code></pre><p>Note: </p>
<ol>
<li>If you are publishing the package publically its name should be unique.</li>
<li>There is a charge of 7$ if you want to publish a private package to npm.
You can refer to this article if you want to publish a private package for free.  <a target="_blank" href="https://dev.to/rajandmr/publishing-private-npm-package-for-free-nd7">Link to Article</a> </li>
</ol>
<p>If you want to publish scoped package publically run this command</p>
<pre><code>npm publish <span class="hljs-comment">--access=public</span>
</code></pre><p>And we are done, Congratulations!!! your react package is now published on npmjs.com.</p>
]]></content:encoded></item><item><title><![CDATA[How to encrypt files in react using Web Crypto API.]]></title><description><![CDATA[Hi! I am Abhijeet Nandvikar. I am a Frontend Developer. Recently I was working on a project which required me to implement end-to-end encryption on files before uploading them to cloud storage. This inspired me to write a blog about it to solidify my...]]></description><link>https://blogs.abhijeetnandvikar.com/how-to-encrypt-files-in-react-using-web-crypto-api</link><guid isPermaLink="true">https://blogs.abhijeetnandvikar.com/how-to-encrypt-files-in-react-using-web-crypto-api</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[encryption]]></category><dc:creator><![CDATA[Abhijeet Nandvikar]]></dc:creator><pubDate>Sat, 29 May 2021 17:36:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1622304328068/cmRbcQ7Wg.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hi! I am <strong>Abhijeet Nandvikar</strong>. I am a Frontend Developer. Recently I was working on a project which required me to implement end-to-end encryption on files before uploading them to cloud storage. This inspired me to write a blog about it to solidify my knowledge and also help other people who are trying to solve a similar problem.</p>
<p><strong>Note: The intention of this blog is just to introduce you to the concept of encryption using Web Crypto API. Do your own research before implementing this in a real project.</strong></p>
<h3 id="heading-what-is-encryption">What is encryption :</h3>
<p>Encryption is the process of taking some data and scrambling it in such a way that its meaning can be derived by only that user who is authorized to do so. Any other user should not understand what this data represents. Data is encrypted and decrypted using a key. One who has the key can only understand the data.</p>
<p><strong>Broadly encryption algorithm is classified into two categories:</strong></p>
<ol>
<li><p><strong>Asymmetric encryption algorithms</strong> use two types of keys, public and private keys to encrypt and decrypt data. Example: RSA algorithm.</p>
</li>
<li><p><strong>Symmetric encryption algorithms</strong>, which use the same key to encrypt and decrypt data. Example: AES, DES, Triple DES algorithm.</p>
</li>
</ol>
<p><strong>Web Crypto API</strong> is provided by the browser to implement cryptography on the front end. It’s faster and much safer than using some third-party libraries. It’s also supported by all major browsers, internet explorer only provides partial support. Now let’s take a look at the steps involved to encrypt and decrypt a file.</p>
<ol>
<li><p>Getting a password from the user.</p>
</li>
<li><p>Generating a digest from the password.</p>
</li>
<li><p>Generating a key from the digest.</p>
</li>
<li><p>Generating an iv (initialization vector).</p>
</li>
<li><p>Getting a file.</p>
</li>
<li><p>Applying encrypt function.</p>
</li>
</ol>
<p>All the methods that we are going to discuss below will be provided window.crypto object.</p>
<h3 id="heading-step-1">STEP 1:</h3>
<p>We are going to encrypt a file using a secret, that only the end-user will know. For this, we will take the password as an input.</p>
<h3 id="heading-step-2">STEP 2:</h3>
<p>The Password taken from the user cannot be used directly as a key for encryption because the Web Crypto API does not allow this. For this, we need to generate a digest first using this password.</p>
<h4 id="heading-what-is-digest">What is Digest?</h4>
<p>A digest is a value generated by a hash function using a message as input, In our case, the password will be the message.</p>
<p>A digest is usually used to perform different tasks:</p>
<ol>
<li><p>generate keys</p>
</li>
<li><p>verify message integrity</p>
</li>
<li><p>store passwords so that they can't be retrieved, but can still be checked</p>
</li>
<li><p>generate pseudo-random numbers etc.</p>
</li>
</ol>
<p>The <strong>crypto.subtle.digest()</strong> method takes two parameters as inputs, type of algorithm and data. The algorithm can be of the following types SHA-1 (but don't use this in cryptographic applications), SHA-256, SHA-384, SHA-512. Data is an array buffer.</p>
<h4 id="heading-what-is-an-array-buffer">What is an Array Buffer?</h4>
<p>The Array Buffer object is used to represent a generic, fixed-length raw binary data buffer. It is an array of bytes, often referred to in other languages as a "byte array".</p>
<p>Therefore we first need to convert our password in the form of an array buffer. For this, we are using TextEncoder Constructor. This converts the string into an array buffer. An enc object has an encoding method that takes a string as an input and outputs an array buffer. An array buffer represents raw data in memory.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getDigest = <span class="hljs-function">(<span class="hljs-params">uid</span>) =&gt;</span> {
  <span class="hljs-keyword">let</span> enc = <span class="hljs-keyword">new</span> TextEncoder();

  <span class="hljs-keyword">return</span> crypto.subtle.digest(<span class="hljs-string">"SHA-256"</span>, enc.encode(uid));
};
</code></pre>
<p>This method will return a promise which will be resolved with a digest value in the form of an array buffer.</p>
<h3 id="heading-step-3">STEP 3:</h3>
<p>Using Digest we are going to generate a key, for this, we use <strong>window.crypto.subtle.importKey()</strong> method. This method has the following parameters:</p>
<ol>
<li><p><strong>Format:</strong> It is a string describing the data format of the key to import. Eg : raw pkcs8, jwk, spki etc. Since we are passing array buffer format will be raw</p>
</li>
<li><p><strong>Key Data</strong>: key data can be an array buffer or a JSONWebKey Object</p>
</li>
<li><p><strong>Algorithm</strong>: It is the name of an encryption algorithm for which we want to generate a key.</p>
</li>
<li><p><strong>Extractable</strong>: It is a Boolean indicating whether it will be possible to export the key using SubtleCrypto.exportKey()</p>
</li>
<li><p><strong>Key Usage</strong>: It is an array that contains information about the usage of key</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getKey</span>(<span class="hljs-params">value</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">window</span>.crypto.subtle.importKey(<span class="hljs-string">"raw"</span>, value, <span class="hljs-string">"AES-GCM"</span>, <span class="hljs-literal">true</span>, [
    <span class="hljs-string">"encrypt"</span>,
    <span class="hljs-string">"decrypt"</span>
  ]);
}
</code></pre>
<p>This method returns a promise which is resolved with a Cryptokey object.</p>
<h3 id="heading-step-4">STEP 4:</h3>
<h4 id="heading-what-is-an-initialization-vector">What is an initialization vector?</h4>
<p>An <strong>initialization vector (IV)</strong> is a sequence of random numbers that can be used along with a secret key for data encryption. This number is also called a nonce. The use of an IV prevents repetition in data encryption, making it more difficult for a hacker using a dictionary attack to find patterns and break a cipher.</p>
<p>Here we are going to use <strong>window.crypto.getRandomValues()</strong> method to generate an iv. We pass an empty byte array of length 12. This method returns a promise which is resolved with an iv.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getiv = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">window</span>.crypto.getRandomValues(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Uint8Array</span>(<span class="hljs-number">12</span>));
};
</code></pre>
<h3 id="heading-step-5">STEP 5:</h3>
<p>One important thing to note here is that the <strong>window.subtle.encrypt()</strong> function only accepts data in the form of an array buffer, so we need to read the input file in the form of an array buffer. For this,s we will use the getFile() method that returns a promise which is resolved with an array buffer containing raw file data. The maximum file size that can be handled depends upon the capacity of the device.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// load the file in the memory</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getFile = <span class="hljs-keyword">async</span> (inputFile) =&gt; {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> inputFile.arrayBuffer();
};
</code></pre>
<h3 id="heading-step-6">STEP 6:</h3>
<p>Now we got all the things necessary to perform encryption on file. Our function takes 3 inputs key, iv, and file. These parameters are then passed to <strong>crypto.subtle.encrypt()</strong> method.</p>
<p>This method takes 3 parameters:</p>
<ol>
<li><p><strong>Algorithm</strong>: It is an object specifying the algorithm to be used and any extra parameters if required. Following algorithms are supported in this method RSA-OAEP, AES-CTR, AES-CBC, and AES-GCM.</p>
</li>
<li><p><strong>Key</strong>: It is a CryptoKey to be used for encryption.</p>
</li>
<li><p><strong>Data</strong>: It is an Array Buffer containing the data to be encrypted.</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> encryptFile = <span class="hljs-keyword">async</span> (key, iv, file) =&gt; {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">window</span>.crypto.subtle.encrypt(
    {
      <span class="hljs-attr">name</span>: <span class="hljs-string">"AES-GCM"</span>,
      <span class="hljs-attr">iv</span>: iv
    },
    key,
    file
  );
};
</code></pre>
<p>Encrypt method will return a promise that is resolved with ciphertext, This ciphertext is also in the form of an array buffer. Finally, in order to save our file to local storage or to the cloud, we need to convert it into a blob.</p>
<p>To Decrypt a file we just have to use crypto. subtle.decrypt() method. This method takes in 3 parameters: initialization vector (iv), crypto key, and ciphertext. It returns a promise which is resolved with an array buffer containing the original file.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> decryptFile = <span class="hljs-function">(<span class="hljs-params">key,iv, cipherText</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">window</span>.crypto.subtle.decrypt(
    {
      <span class="hljs-attr">name</span>: <span class="hljs-string">"AES-GCM"</span>,
      <span class="hljs-attr">iv</span>: iv
    },
    key,
    cipherText
  );
};
</code></pre>
<blockquote>
<p>Note: Value of initialization vector(iv) should be the same as used while encryption a file.</p>
</blockquote>
<h4 id="heading-here-is-the-link-to-the-working-demo-working-demohttpsweb-encryption-demonetlifyapp">Here is the link to the working demo: <a target="_blank" href="https://web-encryption-demo.netlify.app/">Working Demo</a></h4>
<h4 id="heading-here-is-the-link-for-code-link-to-codehttpsgithubcomabhijeetnandvikarweb-encryption-demo">Here is the link for code: <a target="_blank" href="https://github.com/AbhijeetNandvikar/web-encryption-demo">Link to code</a></h4>
]]></content:encoded></item></channel></rss>