DEV Community: Vikrant Bhat The latest articles on DEV Community by Vikrant Bhat (@bhatvikrant). https://dev.to/bhatvikrant 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%2F398470%2Fd42b354b-a86b-4759-aae5-c30fbcc35290.jpg DEV Community: Vikrant Bhat https://dev.to/bhatvikrant en Optimize your workflow with Tailwind CSS: Get class completions and hover previews for classes assigned to variables in VScode Vikrant Bhat Sun, 12 Mar 2023 13:57:33 +0000 https://dev.to/bhatvikrant/optimize-your-workflow-with-tailwind-css-get-class-completions-and-hover-previews-for-classes-assigned-to-variables-in-vscode-44pj https://dev.to/bhatvikrant/optimize-your-workflow-with-tailwind-css-get-class-completions-and-hover-previews-for-classes-assigned-to-variables-in-vscode-44pj <blockquote> <p>TL;DR</p> <p>This article provides instructions on how to enable auto-completion and hover IntelliSense for TailwindCSS classes in VScode. To do this, users must add a regex to the VScode settings that matches the desired custom HTML attributes (variable names).</p> </blockquote> <p>If you've been developing apps using <a href="proxy.php?url=https://tailwindcss.com/">TailwindCSS</a> for some time, then it is inevitable that you will or must have already encountered this issue in VScode.</p> <h2> The problem 🚧 </h2> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--eZYVCFOG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shffivsotutoe5cc33zd.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--eZYVCFOG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/shffivsotutoe5cc33zd.gif" alt="The problem" width="600" height="369"></a></p> <p>When you assign <code>className</code> to a <code>div</code> then you get auto-completion and the applied CSS style when you hover over the added tailwind class.</p> <blockquote> <p>⚡️ Note: <a href="proxy.php?url=https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss">Tailwind CSS IntelliSense VScode extension</a> must be installed in your VScode to get auto-completion and hover IntelliSense.</p> </blockquote> <p>But if you create a variable called <code>containerClass</code> and then try assigning tailwind classes to it, then you won't get the same IntelliSense, which is fine for most people 🤝, but if you're a productivity fanatic like me, then this is not acceptable!</p> <p>First, let's try to understand why doesn't the <code>containerClass</code> gets the same inference.</p> <h2> The why ❓ </h2> <p>The <em>Tailwind CSS IntelliSense</em> VScode extension, by default only looks for <code>class</code>, <code>className</code> and <code>ngClass</code> HTML attributes to provide class completions, hover previews, linting, etc.</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--3ijuURFT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iia7wahxh6xbakrxduir.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--3ijuURFT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iia7wahxh6xbakrxduir.png" alt="Search 'tailwindcss' in vscode settings" width="880" height="299"></a></p> <p>We can check this by searching for <code>tailwindcss</code> in our VScode settings, and the first result shows us the default HTML attributes for which class completions, hover previews, linting, etc are provided.</p> <p>Hence we do not get class completions and hover previews when we assign tailwind classes to a variable.</p> <h2> The solution 💰 </h2> <p>By now you've probably already understood what needs to be done to mitigate this.</p> <p>In settings, after searching for <code>tailwindcss</code>, we need to:</p> <ol> <li><p>Click on Add Item button</p></li> <li><p>Add regex that matches the desired custom HTML attributes (variable names) - <code>.*Class</code> , <code>.*ClassName</code> .</p></li> </ol> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--7uUZVjsk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2rbb1wa6kmytwrfrc51.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--7uUZVjsk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i2rbb1wa6kmytwrfrc51.png" alt="default setting" width="880" height="335"></a></p> <p>Done! ✅</p> <p>Now you should be able to get class completions and hover previews when you assign tailwind classes to a variable that ends with <code>Class</code> or <code>ClassName</code> .</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--0VO41SUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpurtrowozauvjz70xw4.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--0VO41SUW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tpurtrowozauvjz70xw4.gif" alt="Working Solution" width="600" height="369"></a></p> <h2> Epilogue 🌻 </h2> <p>For most people, this might not be of the utmost importance, but I am always on the lookout for the tiniest improvements in my Development Experience! Feel free to share any suggestions you might have for me 😇.</p> <p>Originally, my plan was to compose a Twitter thread about this topic. However, upon further consideration, I discovered that tweets are not very searchable. As a result, I decided to write a more in-depth blog post instead.</p> <p>If you like quick tips like this then you might also like my other blog posts. I also share a lot of React, Javascript, Typescript, expo, nextjs content on my <a href="proxy.php?url=https://twitter.com/vikrantbhat1022/"><em>twitter</em></a>.</p> <p>Thank you for taking the time to read this blog! Your support is greatly appreciated.</p> tailwindcss vscode dx javascript A Step-by-Step Guide to Share images from Your Expo React Native App to Instagram Stories Vikrant Bhat Tue, 28 Feb 2023 16:18:24 +0000 https://dev.to/bhatvikrant/a-step-by-step-guide-to-share-images-from-your-expo-react-native-app-to-instagram-stories-1feb https://dev.to/bhatvikrant/a-step-by-step-guide-to-share-images-from-your-expo-react-native-app-to-instagram-stories-1feb <p>Let's get started with this step-by-step guide to share images from your Expo React Native App to Instagram Stories! With this guide, you will be able to easily install the necessary libraries - react-native-view-shot and react-native-share - and create a component with the example code. I also share some tips for debugging if you get stuck and a few resources to help you out. So, let's get started!</p> <h2> Steps </h2> <h3> Step 1: Create an expo app or open an existing expo-managed app </h3> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>npx create-expo-app my-app <span class="o">&amp;&amp;</span> <span class="nb">cd </span>my-app </code></pre> </div> <h3> Step 2: Install the following mentioned libraries: </h3> <ol> <li><p><a href="proxy.php?url=https://www.npmjs.com/package/react-native-view-shot" rel="noopener noreferrer">react-native-view-shot</a> - to capture a React Native View as an image.</p></li> <li><p><a href="proxy.php?url=https://www.npmjs.com/package/react-native-share" rel="noopener noreferrer">react-native-share</a> - to share the captured image as a sticker to your Instagram stories.</p></li> </ol> <h3> Step 3: Copy the following example code as a component </h3> <blockquote> <p>Ps: I've tried to explain as much as I can within the code snippet below, if there are still any questions, please feel free to ask!<br> </p> </blockquote> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="k">import</span> <span class="p">{</span> <span class="nx">useRef</span><span class="p">,</span> <span class="nx">useState</span><span class="p">,</span> <span class="nx">useEffect</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">react</span><span class="dl">'</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">Text</span><span class="p">,</span> <span class="nx">View</span><span class="p">,</span> <span class="nx">Button</span><span class="p">,</span> <span class="nx">Platform</span><span class="p">,</span> <span class="nx">Linking</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-native</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">captureRef</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-native-view-shot</span><span class="dl">"</span><span class="p">;</span> <span class="k">import</span> <span class="nx">Share</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-native-share</span><span class="dl">"</span><span class="p">;</span> <span class="kd">const</span> <span class="nx">App</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">viewRef</span> <span class="o">=</span> <span class="nf">useRef</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span> <span class="c1">// ref used to mark the View to be screenshotted 📸, check the returned JSX below</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">hasInstagramInstalled</span><span class="p">,</span> <span class="nx">setHasInstagramInstalled</span><span class="p">]</span> <span class="o">=</span> <span class="nf">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span> <span class="c1">// State to track if Instagram is installed on user's device or not</span> <span class="nf">useEffect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="k">if </span><span class="p">(</span><span class="nx">Platform</span><span class="p">.</span><span class="nx">OS</span> <span class="o">===</span> <span class="dl">"</span><span class="s2">ios</span><span class="dl">"</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// If platform is IOS then check if instagram is installed on the user's device using the `Linking.canOpenURL` API</span> <span class="nx">Linking</span><span class="p">.</span><span class="nf">canOpenURL</span><span class="p">(</span><span class="dl">"</span><span class="s2">instagram://</span><span class="dl">"</span><span class="p">).</span><span class="nf">then</span><span class="p">((</span><span class="nx">val</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="nf">setHasInstagramInstalled</span><span class="p">(</span><span class="nx">val</span><span class="p">),</span> <span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">// Else check on android device if instagram is installed in user's device using the `Share.isPackageInstalled` API</span> <span class="nx">Share</span><span class="p">.</span><span class="nf">isPackageInstalled</span><span class="p">(</span><span class="dl">"</span><span class="s2">com.instagram.android</span><span class="dl">"</span><span class="p">).</span><span class="nf">then</span><span class="p">(</span> <span class="p">({</span> <span class="nx">isInstalled</span> <span class="p">})</span> <span class="o">=&gt;</span> <span class="nf">setHasInstagramInstalled</span><span class="p">(</span><span class="nx">isInstalled</span><span class="p">),</span> <span class="p">);</span> <span class="p">}</span> <span class="p">},</span> <span class="p">[]);</span> <span class="k">async</span> <span class="kd">function</span> <span class="nf">captureAndShare</span><span class="p">()</span> <span class="p">{</span> <span class="k">try</span> <span class="p">{</span> <span class="c1">// Capture the screenshot of the element and store it into the uri variable</span> <span class="kd">const</span> <span class="nx">uri</span> <span class="o">=</span> <span class="k">await</span> <span class="nf">captureRef</span><span class="p">(</span><span class="nx">viewRef</span><span class="p">,</span> <span class="p">{</span> <span class="na">format</span><span class="p">:</span> <span class="dl">"</span><span class="s2">png</span><span class="dl">"</span><span class="p">,</span> <span class="na">quality</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="p">});</span> <span class="k">if </span><span class="p">(</span><span class="nx">hasInstagramInstalled</span><span class="p">)</span> <span class="p">{</span> <span class="k">await</span> <span class="nx">Share</span><span class="p">.</span><span class="nf">shareSingle</span><span class="p">({</span> <span class="na">appId</span><span class="p">:</span> <span class="dl">""</span><span class="p">,</span> <span class="c1">// Note: replace this with your own appId from facebook developer account, it won't work without it. (https://developers.facebook.com/docs/development/register/)</span> <span class="na">stickerImage</span><span class="p">:</span> <span class="nx">uri</span><span class="p">,</span> <span class="na">social</span><span class="p">:</span> <span class="nx">Share</span><span class="p">.</span><span class="nx">Social</span><span class="p">.</span><span class="nx">INSTAGRAM_STORIES</span><span class="p">,</span> <span class="na">backgroundBottomColor</span><span class="p">:</span> <span class="dl">"</span><span class="s2">#1D1D1D</span><span class="dl">"</span><span class="p">,</span> <span class="c1">// You can use any hexcode here and below</span> <span class="na">backgroundTopColor</span><span class="p">:</span> <span class="dl">"</span><span class="s2">#1D1D1D</span><span class="dl">"</span><span class="p">,</span> <span class="na">backgroundImage</span><span class="p">:</span> <span class="dl">'</span><span class="s1">...</span><span class="dl">'</span><span class="p">,</span> <span class="c1">// This field is optional like the other fields (except appId) and you have to put a base64 encoded image here if you want to use it!</span> <span class="p">});</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">// If instagram is not installed in user's device then just share using the usual device specific bottomsheet (https://react-native-share.github.io/react-native-share/docs/share-open)</span> <span class="k">await</span> <span class="nx">Share</span><span class="p">.</span><span class="nf">open</span><span class="p">({</span> <span class="na">url</span><span class="p">:</span> <span class="nx">uri</span> <span class="p">});</span> <span class="p">}</span> <span class="p">}</span> <span class="k">catch </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span> <span class="nx">console</span><span class="p">.</span><span class="nf">error</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="k">return </span><span class="p">(</span> <span class="o">&lt;&gt;</span> <span class="o">&lt;</span><span class="nx">View</span> <span class="nx">ref</span><span class="o">=</span><span class="p">{</span><span class="nx">viewRef</span><span class="p">}</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nx">Text</span> <span class="nx">style</span><span class="o">=</span><span class="p">{{</span> <span class="na">color</span><span class="p">:</span> <span class="dl">"</span><span class="s2">red</span><span class="dl">"</span> <span class="p">}}</span><span class="o">&gt;</span><span class="nx">Hello</span> <span class="nx">world</span><span class="o">!&lt;</span><span class="sr">/Text</span><span class="err">&gt; </span> <span class="o">&lt;</span><span class="sr">/View</span><span class="err">&gt; </span> <span class="o">&lt;</span><span class="nx">Button</span> <span class="nx">onPress</span><span class="o">=</span><span class="p">{</span><span class="nx">captureAndShare</span><span class="p">}</span> <span class="nx">title</span><span class="o">=</span><span class="dl">'</span><span class="s1">Capture &amp; Share</span><span class="dl">'</span> <span class="o">/&gt;</span> <span class="o">&lt;</span><span class="sr">/</span><span class="err">&gt; </span> <span class="p">)</span> <span class="p">}</span> <span class="k">export</span> <span class="k">default</span> <span class="nx">App</span><span class="p">;</span> </code></pre> </div> <blockquote> <p>Note: for testing react-native-share's functionality in your expo managed app, you will have to make use of <a href="proxy.php?url=https://docs.expo.dev/development/introduction/" rel="noopener noreferrer">Expo development builds</a>.</p> </blockquote> <h2> Tips for debugging if stuck </h2> <ol> <li><p>APIs from various packages and Instagram are ever-changing, hence if you are stuck, I would highly recommend to go and search in their GitHub issues and PRs tab, it's very likely that someone has already faced it. I would also be happy to help you out if that doesn't work out 😇</p></li> <li><p>Make sure that you test on both IOS and Android devices before releasing as there might be some things that don't work across platforms and you might need to handle them.</p></li> </ol> <h2> Resources </h2> <ol> <li><p><a href="proxy.php?url=https://developers.facebook.com/docs/instagram/sharing-to-stories" rel="noopener noreferrer">Sharing to Stories</a> - Facebook docs for sharing from apps to stories, it does not have anything specific to react-native or expo, but it's a must-read to understand the API and values it accepts.</p></li> <li><p><a href="proxy.php?url=https://www.youtube.com/watch?v=3HkHDjLkqRo&amp;t=733s&amp;ab_channel=JimmyCook" rel="noopener noreferrer">Create an image from a React Native component and share it on social media</a> - This video is a little old but it gives you a good idea of the problem and the solution.</p></li> <li><p><a href="proxy.php?url=https://docs.expo.dev/development/introduction/" rel="noopener noreferrer">What are development builds and how to set them up</a> - comprehensive, complete, and up-to-date docs from the expo team. <a href="proxy.php?url=https://www.youtube.com/watch?v=id0Im72UN6w&amp;t=441s&amp;ab_channel=Expo" rel="noopener noreferrer">[Video alternative]</a></p></li> </ol> opensource software discuss tools Don't lose your Github contributions when you leave an organization Vikrant Bhat Sat, 28 May 2022 06:33:56 +0000 https://dev.to/bhatvikrant/dont-lose-your-github-contributions-when-you-leave-an-organization-10pf https://dev.to/bhatvikrant/dont-lose-your-github-contributions-when-you-leave-an-organization-10pf <p>As Software engineers there are often times in our careers when we change jobs, now this is a good thing since you get a significant raise 💰, the excitement of joining a new organization is also there and maybe you are also re-locating (to Bangalore?) to a new place. </p> <p>In this excitement, most of us forget that soon you will be kicked out of your previous Github organization, where you might have made hundreds if not thousands of commits during your tenure and once you are kicked out, all of these commits will disappear in a ✨ jiffy ✨ from you Github profile.</p> <p>If you are someone like me who cares deeply about their Github profile, then you will be in deep regret (<a href="proxy.php?url=https://github.com/isaacs/github/issues/1138">like this person</a>) if you don't do the needful to retain those contributions on your profile.<br> A Github profile for software engineers is like their resume or at least I treat it like one, hence it's important to keep it up-to-date, authentic and relevant. Having a consistent contributions graph on your Github profile helps you get noticed by possible future recruiters and in general, it shows your consistency as a software engineer.</p> <blockquote> <p>You can checkout my Github profile <a href="proxy.php?url=https://github.com/bhatvikrant">here</a></p> </blockquote> <p>Now let's get into the meat of it 🎯</p> <h1> It is important to understand when commits are shown </h1> <p>Commits will appear on your contributions graph if they meet all of the following conditions:</p> <ol> <li>The email address used for the commits is associated with your account on GitHub.com.</li> <li>The commits were made in a standalone repository, not a fork.</li> <li>The commits were made in the repository's default branch</li> </ol> <p>In addition, at least one of the following must be true:</p> <ul> <li>You are a collaborator on the repository or are a member of the organization that owns the repository.</li> <li>You have forked the repository.</li> <li>You have opened a pull request or issue in the repository.</li> <li>✨ <strong>You have starred the repository.</strong> ✨</li> </ul> <h1> So what can I do to keep my hard-earned contributions? </h1> <p>Star the repositories you are contributing to in your organization. That way, your commits to those repositories will remain in your contributions graph even if you leave the organization that owns the repository or delete your fork of the repository.</p> <h1> Before you leave your company, make sure you update the following information in your personal account: </h1> <ol> <li><p>Unverify your company email address by deleting it in your Email settings. You can then re-add it without verifying to keep any associated commits linked to your account.</p></li> <li><p>Change your primary email address from your company email to your personal email.</p></li> <li><p>Verify your new primary email address.</p></li> </ol> <h1> FAQs </h1> <p>1) Regarding the advice to star the repos before leaving, does this mean that only commits post-starring will remain? Or is starring once sufficient to retain all past commits?</p> <p>Ans - all commits will remain, so star the repositories as soon as you can just in case.</p> <p>2) What if commits were made using a company email?</p> <p>Ans - Unverify your company email address by deleting it in your Email settings. You can then re-add it without verifying to keep any associated commits linked to your account. ( <a href="proxy.php?url=https://docs.github.com/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings/best-practices-for-leaving-your-company">refer</a> )</p> <h1> References </h1> <ol> <li><a href="proxy.php?url=https://github.com/isaacs/github/issues/1138">https://github.com/isaacs/github/issues/1138</a></li> <li><a href="proxy.php?url=https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/best-practices-for-leaving-your-company">https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/best-practices-for-leaving-your-company</a></li> <li><a href="proxy.php?url=https://github.community/t/getting-all-your-commits-in-your-contributions-graph/10186">https://github.community/t/getting-all-your-commits-in-your-contributions-graph/10186</a></li> <li><a href="proxy.php?url=https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-graphs-on-your-profile/why-are-my-contributions-not-showing-up-on-my-profile">https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-profile/managing-contribution-graphs-on-your-profile/why-are-my-contributions-not-showing-up-on-my-profile</a></li> </ol> <blockquote> <p>If this blog helped you then please share it with other engineers out there, I don't want any engineer to lose their contributions ever :)</p> </blockquote> github org tutorial javascript .reduce() Polyfill Vikrant Bhat Sun, 09 Jan 2022 15:48:24 +0000 https://dev.to/bhatvikrant/reduce-polyfill-3g03 https://dev.to/bhatvikrant/reduce-polyfill-3g03 <blockquote> <p>The full source code for the polyfill is available an the end ⬇️</p> </blockquote> <h2> What is a polyfill? </h2> <p>A polyfill is a piece of code used to provide modern functionality on older browsers that do not natively support it.</p> <h2> Polyfill for Array.prototype.reduce() </h2> <p>We will be writing the polyfill in steps, and in each step we will cover a <code>test case</code>.</p> <blockquote> <p>Note: In first 3 cases we will handle the error conditions</p> </blockquote> <h3> Case 1: Check if <code>this</code> exists, reduce is not called on null or undefined </h3> <p>To write the polyfill, we will create a function called <code>myReduce</code> which will take two arguments which are, a <code>callBack</code> function and the <code>initialValue</code> namely.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{...}</span> </code></pre> </div> <p>In the current case, <code>this</code> refers to the array on which our <code>myReduce</code> is called. </p> <p>For example,<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nx">myReduce</span><span class="p">(...)</span> </code></pre> </div> <p>then, in the above example <code>this</code> refers to the array [1, 2, 3].</p> <p>moving ahead, in the current case, we have to check if <code>this</code> exists and reduce is not called on null or undefined, and if it is, then throw a TypeError ☠️.</p> <p>So, the code for it will look like:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span> <span class="k">this</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span> <span class="dl">'</span><span class="s1">Array.prototype.myReduce is called on null or undefined</span><span class="dl">'</span> <span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <h3> Case 2: Check if <code>callback</code> is a function </h3> <p>To handle this case, we add another check for callback, and throw a TypeError if otherwise.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span> <span class="k">this</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span> <span class="dl">'</span><span class="s1">Array.prototype.myReduce is called on null or undefined</span><span class="dl">'</span> <span class="p">);</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">callback</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">callback</span> <span class="o">!==</span> <span class="dl">'</span><span class="s1">function</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// check for callback to exist, and it should be a function</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">callback</span><span class="p">}</span><span class="s2"> is not a function`</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <h3> Case 3: Reduce on empty array with no initialValue should throw error </h3> <p>To handle this case, we add another if check, and throw a TypeError if otherwise.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span> <span class="k">this</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span> <span class="dl">'</span><span class="s1">Array.prototype.myReduce is called on null or undefined</span><span class="dl">'</span> <span class="p">);</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">callback</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">callback</span> <span class="o">!==</span> <span class="dl">'</span><span class="s1">function</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">callback</span><span class="p">}</span><span class="s2"> is not a function`</span><span class="p">);</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// i.e. if array is empty</span> <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// i.e. if there are less than two arguments, then that means `initialValue` is missing, since callback is a mandatory argument for myReduce function. </span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="dl">'</span><span class="s1">Reduce of empty array with no initial value</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <blockquote> <p>Note: Read more about <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a> here</p> </blockquote> <h3> Case 4: Invoked on empty array with initialValue, returns initialValue </h3> <p>For this, we add an else if block, and check if there are exactly 2 arguments</p> <blockquote> <p>Note: for the sake of readability, I will be only showing the the code under discussion in code snippets.<br> </p> </blockquote> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">...</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// i.e. if array is empty</span> <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// i.e. if there are less than two arguments</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="dl">'</span><span class="s1">Reduce of empty array with no initial value</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// This check means that there are exactly 2 arguments, which will namely be -&gt; `callback` and `initialValue`</span> <span class="k">return</span> <span class="nx">initialValue</span><span class="p">;</span> <span class="c1">// so, in that case return initialValue</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <p>For example,<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">sum</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span> <span class="p">}</span> <span class="p">[].</span><span class="nx">myReduce</span><span class="p">(</span><span class="nx">sum</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="c1">// here `sum` is the callback function and 5 is the initialValue.</span> <span class="c1">// OUTPUT</span> <span class="mi">5</span> </code></pre> </div> <h3> Case 5: Invoked with initialValue </h3> <p>We initialize 2 variables:<br> <code>k</code> equal to 0<br> and, <code>acc</code> equal to <code>initialValue</code> (acc is short for accumulator, because it will be used to accumulate the result)</p> <p><code>acc</code> is set to <code>initialValue</code> because we want our accumulated result to already have the <code>initialValue</code> in it.</p> <blockquote> <p>Note: You may be wondering why are we using the <code>var</code> keyword to declare variables (which is usually a discouraged practice in modern web development), well since the whole point of a polyfill is that it should run in old browsers that don't support latest features yet, hence we are using <code>var</code> which has been a part of JS since the start.</p> </blockquote> <p>We also start a while loop, which runs until <code>k</code> is less than the array's length, and inside the while loop we update the <code>acc</code> variable to <code>callback(acc, this[k], k, this)</code> and increment <code>k</code></p> <p>Now, <code>callback(acc, this[k], k, this)</code> might seem complex at first, so let me break it down.</p> <p>By definition, a callback function in reduce has to take 4 parameters: </p> <ol> <li>accumulator (acc)</li> <li>currentValue (this[k] i.e. the current value of of the array under iteration)</li> <li>currentIndex (k) </li> <li>array (<code>this</code>) </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">...</span> <span class="p">...</span> <span class="kd">var</span> <span class="nx">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">acc</span> <span class="o">=</span> <span class="nx">initialValue</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="nx">k</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span> <span class="nx">acc</span> <span class="o">=</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">acc</span><span class="p">,</span> <span class="k">this</span><span class="p">[</span><span class="nx">k</span><span class="p">],</span> <span class="nx">k</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span> <span class="nx">k</span><span class="o">++</span><span class="p">;</span> <span class="c1">// increment k</span> <span class="p">}</span> <span class="k">return</span> <span class="nx">acc</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>For example,<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">sum</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span> <span class="p">}</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nx">myReduce</span><span class="p">(</span><span class="nx">sum</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="c1">// here 1 is the initialValue.</span> <span class="c1">// OUTPUT</span> <span class="mi">7</span> </code></pre> </div> <h3> Case 6: Invoked without initialValue </h3> <p>For this case, we check if <code>arguments.length</code> is less than 2, because it means that <code>initialValue</code> has not been provided, and if it is less than two then we equate the accumulator to <code>this[k++]</code>, which means the first value of the array (this[0], since k = 0 initially). We also post-increment <code>k</code> by using <code>k++</code>, because we want the while loop to start from index 1 and not from index 0 since the accumulator already has the initialValue as the value at index 0 in the array.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">...</span> <span class="p">...</span> <span class="kd">var</span> <span class="nx">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">acc</span> <span class="o">=</span> <span class="nx">initialValue</span><span class="p">;</span> <span class="k">if</span><span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">){</span> <span class="nx">acc</span> <span class="o">=</span> <span class="k">this</span><span class="p">[</span><span class="nx">k</span><span class="o">++</span><span class="p">]</span> <span class="c1">// update `acc` and increment `k`</span> <span class="p">}</span> <span class="c1">// rest of the code stays the same</span> <span class="k">while</span> <span class="p">(</span><span class="nx">k</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span> <span class="nx">acc</span> <span class="o">=</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">acc</span><span class="p">,</span> <span class="k">this</span><span class="p">[</span><span class="nx">k</span><span class="p">],</span> <span class="nx">k</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span> <span class="nx">k</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nx">acc</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>For example,<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">sum</span><span class="p">(</span><span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">a</span> <span class="o">+</span> <span class="nx">b</span> <span class="p">}</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nx">myReduce</span><span class="p">(</span><span class="nx">sum</span><span class="p">)</span> <span class="c1">// no initialValue provided.</span> <span class="c1">// OUTPUT</span> <span class="mi">6</span> </code></pre> </div> <h2> Complete code </h2> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="kd">function</span> <span class="nx">myReduce</span><span class="p">(</span><span class="nx">callback</span><span class="p">,</span> <span class="nx">initialValue</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span> <span class="o">===</span> <span class="kc">null</span> <span class="o">||</span> <span class="k">this</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span> <span class="dl">'</span><span class="s1">Array.prototype.myReduce is called on null or undefined</span><span class="dl">'</span> <span class="p">);</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">callback</span> <span class="o">||</span> <span class="k">typeof</span> <span class="nx">callback</span> <span class="o">!==</span> <span class="dl">'</span><span class="s1">function</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="s2">`</span><span class="p">${</span><span class="nx">callback</span><span class="p">}</span><span class="s2"> is not a function`</span><span class="p">);</span> <span class="p">}</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="k">throw</span> <span class="k">new</span> <span class="nx">TypeError</span><span class="p">(</span><span class="dl">'</span><span class="s1">Reduce of empty array with no initial value</span><span class="dl">'</span><span class="p">);</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">===</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">initialValue</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="kd">var</span> <span class="nx">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="kd">var</span> <span class="nx">acc</span> <span class="o">=</span> <span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="p">?</span> <span class="k">this</span><span class="p">[</span><span class="nx">k</span><span class="o">++</span><span class="p">]</span> <span class="p">:</span> <span class="nx">initialValue</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="nx">k</span> <span class="o">&lt;</span> <span class="k">this</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">k</span><span class="p">))</span> <span class="p">{</span> <span class="nx">acc</span> <span class="o">=</span> <span class="nx">callback</span><span class="p">(</span><span class="nx">acc</span><span class="p">,</span> <span class="k">this</span><span class="p">[</span><span class="nx">k</span><span class="p">],</span> <span class="nx">k</span><span class="p">,</span> <span class="k">this</span><span class="p">);</span> <span class="p">}</span> <span class="nx">k</span><span class="o">++</span><span class="p">;</span> <span class="p">}</span> <span class="k">return</span> <span class="nx">acc</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>This blogpost is inspired by <a href="proxy.php?url=https://www.youtube.com/watch?v=EgN4qwAQ0eM&amp;ab_channel=DevtoolsTech">this youtube video</a> which does a great job at explanation.</p> <p>Thankyou for reading this article! Let's become friends on <a href="proxy.php?url=https://twitter.com/vikrantbhat1022">twitter</a>🐤 also :)</p> How to add Environment variables in a React Native project with TS Vikrant Bhat Sun, 08 Aug 2021 18:49:11 +0000 https://dev.to/bhatvikrant/how-to-add-environment-variables-in-a-react-native-project-with-ts-2ne5 https://dev.to/bhatvikrant/how-to-add-environment-variables-in-a-react-native-project-with-ts-2ne5 <p>There are a lot of ways in which we can use environment variables in React Native, you can look at many of them listed in <a href="proxy.php?url=https://stackoverflow.com/questions/33117227/setting-environment-variable-in-react-native" rel="noopener noreferrer">this stack-overflow question</a></p> <p>The purpose of this blogpost is to point out and explain the simplest and quickest way to make use of environment variables in your RN project with typescript type checking, you can still follow this blog if you are just using javascript. </p> <p>We will be making use of the handy npm library <a href="proxy.php?url=https://www.npmjs.com/package/react-native-dotenv" rel="noopener noreferrer">react-native-dotenv</a></p> <h2> STEP 1: Install following packages: </h2> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> npm <span class="nb">install </span>react-native-dotenv </code></pre> </div> <p>or</p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> yarn add react-native-dotenv </code></pre> </div> <p>For typescript install additionally:</p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> npm <span class="nb">install</span> <span class="nt">-D</span> @types/react-native-dotenv </code></pre> </div> <p>or </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> yarn add <span class="nt">-D</span> @types/react-native-dotenv </code></pre> </div> <h2> STEP 2: update your babel.config.js </h2> <p>This blogpost uses an expo managed project, hence the <code>babel.config.js</code> will look like</p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code> <span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="nf">function </span><span class="p">(</span><span class="nx">api</span><span class="p">)</span> <span class="p">{</span> <span class="nx">api</span><span class="p">.</span><span class="nf">cache</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span> <span class="k">return</span> <span class="p">{</span> <span class="na">presets</span><span class="p">:</span> <span class="p">[</span><span class="dl">"</span><span class="s2">babel-preset-expo</span><span class="dl">"</span><span class="p">],</span> <span class="na">plugins</span><span class="p">:</span> <span class="p">[</span> <span class="p">[</span> <span class="dl">"</span><span class="s2">module:react-native-dotenv</span><span class="dl">"</span><span class="p">,</span> <span class="p">{</span> <span class="na">moduleName</span><span class="p">:</span> <span class="dl">"</span><span class="s2">@env</span><span class="dl">"</span><span class="p">,</span> <span class="na">path</span><span class="p">:</span> <span class="dl">"</span><span class="s2">.env</span><span class="dl">"</span><span class="p">,</span> <span class="p">},</span> <span class="p">],</span> <span class="p">],</span> <span class="p">};</span> <span class="p">};</span> </code></pre> </div> <p>here, moduleName is the alias we can give to <code>react-native-dotenv</code> library so we can import like:</p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code> <span class="k">import</span> <span class="p">{</span> <span class="nx">ENV_VAR</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@env</span><span class="dl">"</span> </code></pre> </div> <p>instead of:</p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code> <span class="k">import</span> <span class="p">{</span> <span class="nx">ENV_VAR</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">react-native-dotenv</span><span class="dl">"</span> </code></pre> </div> <p>this just makes importing a bit easier :)</p> <h2> STEP 3: Create a <code>.env</code> file in the root directory and add your environment variable </h2> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code> ENV_VAR=some-secret-value </code></pre> </div> <h2> STEP 4: Use the environment variable by importing it </h2> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code> <span class="k">import</span> <span class="p">{</span> <span class="nx">ENV_VAR</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">"</span><span class="s2">@env</span><span class="dl">"</span> </code></pre> </div> <h2> STEP 5: Add typescript support </h2> <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91ibvkhec7xp80ivluin.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91ibvkhec7xp80ivluin.png" alt="Screenshot 2021-08-09 at 12.01.36 AM"></a><br> If you are using Typescript in your project, so you must have observed that typescript is yelling at you in STEP 4.<br> To fix this, we will create an <code>env.d.ts</code> file in the root directory with the following content:</p> <div class="highlight js-code-highlight"> <pre class="highlight typescript"><code> <span class="kr">declare</span> <span class="kr">module</span> <span class="dl">'</span><span class="s1">@env</span><span class="dl">'</span> <span class="p">{</span> <span class="k">export</span> <span class="kd">const</span> <span class="nx">ENV_VAR</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p><em>Wait a second! we are almost done, phew 😅</em></p> <p>After this, you also need to update your <code>tsconfig.json</code> file with: </p> <div class="highlight js-code-highlight"> <pre class="highlight json"><code><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"extends"</span><span class="p">:</span><span class="w"> </span><span class="s2">"expo/tsconfig.base"</span><span class="p">,</span><span class="w"> </span><span class="nl">"compilerOptions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"strict"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="nl">"typeRoots"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">"./types"</span><span class="p">]</span><span class="w"> </span><span class="err">//</span><span class="w"> </span><span class="err">&lt;------</span><span class="w"> </span><span class="err">you</span><span class="w"> </span><span class="err">need</span><span class="w"> </span><span class="err">to</span><span class="w"> </span><span class="err">add</span><span class="w"> </span><span class="err">this</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre> </div> <p>And now we are done!</p> <p>Thank-you for reading this blog! The goal for me writing these specific use-case blogs is to create a directory which I can look back on in future for reference and also help the developer community while at it.<br> Please consider following me here or on <a href="proxy.php?url=https://twitter.com/vikrantbhat1022" rel="noopener noreferrer">Twitter</a> to get updates for my latest publications :)</p> reactnative expo react typescript Free TailwindCSS components to build UI faster Vikrant Bhat Sun, 25 Jul 2021 10:41:06 +0000 https://dev.to/bhatvikrant/free-tailwindcss-components-to-build-faster-ui-l3 https://dev.to/bhatvikrant/free-tailwindcss-components-to-build-faster-ui-l3 <p>As a frontend developer often times we want to just spit out a decently looking UI in a short span of time. The advent of Tailwind CSS has already made our jobs easier but wouldn't it be even better if we could use pre-built good looking components and that too for FREE?</p> <p>That's right, this is a compiled list of free Tailwind CSS components and templates that you can use directly in your side projects or any project for that matter :)</p> <blockquote> <p>🚨 NOTE: Please save this post as I will be updating the list as and when I stumble upon more free resources 🚀.</p> </blockquote> <h2> 1. <a href="proxy.php?url=https://www.tailwind-kit.com/">Tail-kit</a> </h2> <p>Tail-kit gives you access to over 250 free components and free templates, based on Tailwind CSS 2.0. It's all compatible with React, VueJS and Angular applications.</p> <ul> <li><a href="proxy.php?url=https://www.tailwind-kit.com/started">Setup</a></li> <li><a href="proxy.php?url=https://www.tailwind-kit.com/components">Components</a></li> <li><a href="proxy.php?url=https://www.tailwind-kit.com/templates">Templates</a></li> </ul> <p>Extra: You can even make a request for a component <a href="proxy.php?url=https://www.tailwind-kit.com/request">here</a>. Isn't that just amazing 🥳 ?</p> <h2> 2. <a href="proxy.php?url=https://kimia-ui.vercel.app/">Kimia-UI</a> </h2> <p>Provides fully customizable UI Components compatible with Next.js, Gatsby and create-react-app.<br> No installation needed, Just copy and paste a component you want to use</p> <ul> <li><a href="proxy.php?url=https://kimia-ui.vercel.app/configuration">Setup</a></li> <li><a href="proxy.php?url=https://kimia-ui.vercel.app/components/accordion">Components</a></li> <li><a href="proxy.php?url=https://kimia-ui.vercel.app/templates/dashboards">Templates</a></li> </ul> <h2> 3. <a href="proxy.php?url=https://mambaui.com/">Mamba UI</a> </h2> <p>Mamba UI is a free, open-source collection of beautiful UI elements based on Tailwind CSS that make it easy for anyone to build a website in minutes.</p> <ul> <li><a href="proxy.php?url=https://mambaui.com/docs">Setup</a></li> <li><a href="proxy.php?url=https://mambaui.com/components">Components</a></li> <li><a href="proxy.php?url=https://mambaui.com/templates">Templates</a></li> </ul> <h2> 4. <a href="proxy.php?url=https://merakiui.com/">Meraki UI</a> </h2> <p>Beautiful Tailwind CSS components that support RTL languages &amp; fully responsive based on Flexbox &amp; CSS Grid with elegant Dark Mode.</p> <ul> <li><a href="proxy.php?url=https://merakiui.com/">Components</a></li> </ul> <h2> 5. <a href="proxy.php?url=https://tailblocks.cc/">Tailblocks</a> </h2> <p>Ready-to-use Tailwind CSS blocks<br> 60+ Blocks, Responsive, Dark Mode Support, Color Variations</p> <ul> <li><a href="proxy.php?url=https://tailblocks.cc/">Components</a></li> </ul> <h2> 6. <a href="proxy.php?url=https://www.salvia-kit.com/">Salvia-Kit</a> </h2> <p>Built with Tailwind CSS, they are fully customizable and without external dependencies. Each dashboard has 4 variants. one for create-react-app, Next.js, Vue with vite and Nuxt.</p> <ul> <li><a href="proxy.php?url=https://www.salvia-kit.com/dashboard/all">Components</a></li> </ul> <h2> NEW ADDITIONS: </h2> <h2> 7. <a href="proxy.php?url=https://daisyui.com/">DaisyUI</a> </h2> <p>Clean HTML with component classes<br> Customizable and themeable<br> Pure CSS, No dependencies</p> <ul> <li><a href="proxy.php?url=https://daisyui.com/docs/install">Setup</a></li> <li><a href="proxy.php?url=https://daisyui.com/components/alert">Components</a></li> </ul> <p>Thankyou everyone! that is it for now, but I will be updating this list, you can also contribute to this exhaustive list by commenting below or by reaching out to me on <a href="proxy.php?url=https://twitter.com/vikrantbhat1022">twitter</a>🐤, and I will add them here with credits :)</p> tailwindcss css react components Google outage: Official explanation from Google Vikrant Bhat Sat, 19 Dec 2020 10:59:56 +0000 https://dev.to/bhatvikrant/google-outage-official-explanation-from-google-2jo9 https://dev.to/bhatvikrant/google-outage-official-explanation-from-google-2jo9 <p>You might be aware that Google had a global level outage recently which impacted all their services from YouTube, GDrive to GCP and everything in between, infact even the Google oAuth was down, that means if you tried to login/signup into any website that uses Google oAuth then it would have failed during those 47 minutes of downtime.</p> <p>Some on the Twitter rightly claimed that everyone could access YouTube without login, i.e browsing from the incognito window. <br> The reason why people could access YouTube without logging in was<br> </p> <p><code>The Google User ID Service maintains a unique identifier for every account and handles authentication credentials for OAuth tokens and cookies. It stores account data in a distributed database, which uses Paxos protocols to coordinate updates. For security reasons, this service will reject requests when it detects outdated data.</code><br> </p> <p>So what this basically means is that their central Authentication management system was affected and thats why everyone could stream YouTube videos from an incognito window since YouTube allows its users to view YouTube without logging in.</p> <p>Check <a href="proxy.php?url=https://status.cloud.google.com/incident/zall/20013">this</a> blog for the official transcript from Google and detailed explanation of the outage. </p> <p>Were you online at the time of the outage? Are you a developer? How did you do your work for those 47 minutes without Google😁? Come let's chat about this below✌️</p> googlecloud googleoutage explanation 4 PRs done, I need more! Vikrant Bhat Wed, 30 Sep 2020 21:39:17 +0000 https://dev.to/bhatvikrant/4-prs-done-i-need-more-a99 https://dev.to/bhatvikrant/4-prs-done-i-need-more-a99 <p><a href="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw1hxmbaz7htitspeh7zu.jpg" class="article-body-image-wrapper"><img src="proxy.php?url=https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fw1hxmbaz7htitspeh7zu.jpg" alt="Alt Text"></a><br> I just completed my 4 hacktoberfest 2020 PRs! <br> Do you guys have any suggestions for open source repos that need help in React / Javascript? Please let me know 😁</p> hacktoberfest beginners 4prs 7 things I learned as a Software Developer Vikrant Bhat Sun, 20 Sep 2020 15:25:16 +0000 https://dev.to/bhatvikrant/7-things-i-learned-as-a-software-developer-m7f https://dev.to/bhatvikrant/7-things-i-learned-as-a-software-developer-m7f <p>Last week marked my first year as a Software Developer 🎉</p> <p><a href="proxy.php?url=https://i.giphy.com/media/14udF3WUwwGMaA/giphy.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://i.giphy.com/media/14udF3WUwwGMaA/giphy.gif" alt="Happy"></a></p> <p>I learned a lot of things, but the following 7 stick out. My hope is that at least one of them proves useful in your journey🎢.</p> <ol> <li><p><strong>Take notes</strong> ✏️<br> Everyone forgets things. You might have to revisit the StackOverflow solution or a blog that helped you understand a certain concept. Save yourself some time and create a noting system and start writing down helpful resources, advice from managers, how you solved a problem, etc. <br> I personally started noting down links to important resources on an excel sheet (let me know if you have a better workflow!) and it has definitely saved me some googling and re-research time. </p></li> <li><p><strong>Know the WHY</strong> ⍰<br> Don't just copy/paste the code without understanding what it does. It might solve your problem at hand, but you will have that knowledge gap moving forward. <br> You don't want massive technical knowledge debt 5 years down the road!</p></li> <li><p><strong>Speak Up for Yourself</strong> 🗣<br> No one knows what you need except for you - so don't expect your managers to read your 🧠. Need more support? Ask for it. Have some ideas? Discuss. </p></li> <li><p><strong>Mentor Others</strong> 👥<br> You don't have to wait until you're mid-level to start teaching or helping others (Even if you teach one thing that stays with them, that is mentoring! - to some, it might sound like a stretch, but it's good enough to get you started). Others who are a notch or two below your level will benefit from your knowledge. Not only that, but teaching is a great way to solidify your existing skills. 💪🏻</p></li> <li><p><strong>Ask Questions</strong> ⁉️<br> Don't be the dev who asks questions every 5 minutes without Googling beforehand. But also don't be the dev who holds up a feature because they were stuck on a problem and waited 2 days to ask for help.<br> There are no 👏🏻stupid👏🏻questions👏🏻</p></li> <li><p><strong>Have a Hobby</strong> ⚽️<br> No matter how much coffee you've had, your 🧠 isn't meant to code 24/7. Give your mind rest and space to be creative by doing other activities you enjoy. Otherwise, risk burnout. Besides, having other interests can make you more fun to work with.</p></li> <li><p><strong>Don't Take Things Personally</strong> 🙃<br> You are not your code. Learn to view it as temporary. As part of a team, you'll see it change over time for reasons that have nothing to do with your abilities - the codebase grows, business requirements change, code reviews happen, etc.</p></li> </ol> <p>I started with <a href="proxy.php?url=http://reactjs.org/">React</a> on day one, not knowing much about it. But today after a year I can confidently say that I have worked with awesome Javascript technologies &amp; tools ranging from — <em>ReactJS, ReactNative, NodeJS, GatsbyJS, Jest …. firebase, AWS, netlify, vercel</em> and countless others.</p> <blockquote> <p>No matter what gets thrown at me, I’ll strive to find a solution for it. After all thats what it means to be a Problem Solver aka Software Developer :)</p> </blockquote> <p>I would also like to thank my mentors <a href="proxy.php?url=https://www.linkedin.com/in/akshatgupta10/">Akshat Gupta</a> &amp; <a href="proxy.php?url=https://www.linkedin.com/in/rajatjohri007/">Rajat Johri</a> for giving me this wonderful opportunity. Your vision and determination in your respective fields of expertise has given me a unique perspective.</p> todayilearned software developer Open any public GitHub repo in Codesandbox in 3 seconds Vikrant Bhat Sun, 23 Aug 2020 14:44:44 +0000 https://dev.to/bhatvikrant/open-any-public-github-repo-in-codesandbox-in-3-seconds-2il2 https://dev.to/bhatvikrant/open-any-public-github-repo-in-codesandbox-in-3-seconds-2il2 <p>If you are someone who wants to <em>quickly just lookup some code in a GitHub repository</em> or even fork or edit it, then this is a good <strong>handy trick</strong> to know.</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--5XpVuuyT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7bvxnodoea6b3j3kysie.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--5XpVuuyT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/7bvxnodoea6b3j3kysie.gif" alt="Alt Text"></a></p> <blockquote> <p>NOTE: If you are not a PRO member of <strong>codesandbox</strong> then the trick will work only on <em>Public repositories</em></p> </blockquote> <p>Steps to follow (if the GIF doesn't sum it up 😜): </p> <p><strong>STEP 1:</strong> Open any <em>Public</em> GitHub repository.<br> <strong>STEP 2:</strong> Go to the URL and append 'box' to your github.com URL in-between 'hub' and '.com' and it will redirect to CodeSandbox.</p> <p>Here's an example:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>Change the GitHub URL: https://github.com/bhatvikrant/react-thumbnail-player To: https://githubbox.com/bhatvikrant/react-thumbnail-player </code></pre> </div> <p>And that's all you have to do!</p> <p><a href="proxy.php?url=https://codesandbox.io/docs/importing">Check out the Codesandbox docs to learn more</a></p> github devops tutorial Javascript (ES2020) **Nullish Coalescing_( ?? ) and Optional Chaining ( ?. )Explained Vikrant Bhat Sat, 04 Jul 2020 22:41:50 +0000 https://dev.to/bhatvikrant/javascript-es2020-nullish-coalescing-and-optional-chaining-explained-3pkg https://dev.to/bhatvikrant/javascript-es2020-nullish-coalescing-and-optional-chaining-explained-3pkg <h3> Nullish Coalescing operator ( ?? ) </h3> <p>It is a logical operator that <strong>returns</strong> its <strong>right-hand side operand</strong> when its <strong>left-hand side operand</strong> is <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null">null</a> or <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a>, and otherwise returns its left-hand side operand.</p> <p>let's see some use-cases that you might encounter frequently, where the <em>( ?? )</em> operator can make your life easier :)</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--qVnMxWAs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2Ah3I66WNSusebivPHYGRgJA.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--qVnMxWAs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2Ah3I66WNSusebivPHYGRgJA.png" alt=""></a></p> <p>Code snippet — 1.1</p> <p>The most common use-case is accessing a value from a nested <em>Object</em> in javascript.</p> <p>In Code snippet-1.1 you can see that we are trying to access the key ‘<em>name’</em> from the data object, which is a nested object, and it gives us the expected result.</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--wtpNmdwZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2ANtTSfQPqHDY6uzexcaSXCw.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--wtpNmdwZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2ANtTSfQPqHDY6uzexcaSXCw.png" alt=""></a></p> <p>Code snippet — 1.2</p> <p>In Code snippet-1.2 you can see that now the nested data object doesn't contain the <em>‘name’</em> key. And when we try to access the <em>‘name’ key from it, we get undefined.</em></p> <p>Getting an undefined value is often <em>not desirable</em>. You might want to set a default value if the key that you are trying to access is sometimes undefined.</p> <p>This can be tackled using the logical ‘<em>OR</em>’ operator ( || ), like this:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">profile</span><span class="p">.</span><span class="nx">name</span> <span class="o">||</span> <span class="err">‘</span><span class="nx">John</span> <span class="nx">Doe</span><span class="err">’</span><span class="p">)</span> </code></pre> </div> <p>This makes sure that if <em>data.profile.name</em> is <em>undefined</em> then <em>‘John Doe’</em> is shown. But this is still not perfect*,* lets have a look why,</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s---VV-z_PU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AMbglk3_u5Wg7-CBW4xf7vg.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s---VV-z_PU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AMbglk3_u5Wg7-CBW4xf7vg.png" alt=""></a></p> <p>Code snippet —1. 3</p> <p>What if the initial value of the <em>key</em> ‘<em>age’</em> is 0 (which is actually a valid age). In this case, we would get 21 as the output. Which is again not the desired behavior.</p> <p>This happens because <strong>0</strong> in javascript is considered a <strong>falsy</strong> value.</p> <p>So, until now what we had to do is:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="k">if</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">profile</span><span class="p">.</span><span class="nx">name</span> <span class="o">==</span> <span class="kc">undefined</span> <span class="o">||</span> <span class="nx">data</span><span class="p">.</span><span class="nx">profile</span><span class="p">.</span><span class="nx">name</span> <span class="o">==</span> <span class="kc">null</span> <span class="p">)</span> <span class="p">{</span> <span class="nx">keep</span> <span class="nx">the</span> <span class="nx">value</span> <span class="k">of</span> <span class="nx">name</span> <span class="k">as</span> <span class="err">‘</span><span class="nx">John</span> <span class="nx">Doe</span><span class="err">’</span><span class="p">}</span> <span class="k">else</span><span class="p">{</span> <span class="nx">keep</span> <span class="nx">the</span> <span class="nx">provided</span> <span class="nx">value</span> <span class="k">of</span> <span class="nx">name</span><span class="p">}</span> </code></pre> </div> <p>This makes your code unnecessarily long, and many inexperienced programmers (including me when I was starting! 🤓 ) introduce bugs unknowingly.</p> <blockquote> <p><em>#Tip: Incomplete knowledge is more dangerous than no knowledge.</em></p> </blockquote> <p>But now with the introduction of <strong>Nullish Coalescing Operator <em>( ?? )</em></strong> in <em>ES2020,</em> we can save a lot of time and bugs!</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--eXp1IeYo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2ANyJkHrjshn0EGz7EqQW9Bw.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--eXp1IeYo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2ANyJkHrjshn0EGz7EqQW9Bw.png" alt=""></a></p> <p>Code snippet —1. 4</p> <p>All we have to do is use the <strong>( ?? )</strong> operator in the place of ( || ), as simple as that! And that's all you have to do.</p> <p>Now this will log 21 only when the value of age is <strong><em>null</em></strong> or <strong><em>undefined.</em></strong> Which is what we expect.</p> <h3> Optional Chaining operator ( ?. ) </h3> <p>The <strong>optional chaining</strong> operator <code>?.</code> permits reading the value of a property located deep within a chain of connected objects without having to validate that each reference in the chain is valid.</p> <p>let's understand this with the help of an example,</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ScQG0akw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AD0l6eaZZllt3HnbSkstfaQ.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--ScQG0akw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AD0l6eaZZllt3HnbSkstfaQ.png" alt=""></a></p> <p>Code snippet — 2.1</p> <p>We know from our previous experiences that if we try to access a key that doesn't exist inside an object, we get undefined. <em>( see Code snippet-2.1)</em></p> <p>We are trying to access <em>age</em> (which is not present) from the <em>data</em> object. Hence we get undefined.</p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--FtM6983X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2A2vWYxoBGsIjxkTG3r0anGA.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--FtM6983X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2A2vWYxoBGsIjxkTG3r0anGA.png" alt=""></a></p> <p>Code snippet — 2.2 🔗 <a href="proxy.php?url=https://codesandbox.io/s/nested-object-error-example-x3z8n">check out the codesandbox</a></p> <p>Now, what if we try to access a nested <em>key</em> that doesn't exist.</p> <p>As you can see in the Code snippet — 2.2 that we would get an error.</p> <p>So if we have two levels of undefined, then we get an error.</p> <p>This issue can be resolved using the logical <em>‘AND’</em> (&amp;&amp;) operator, like this:</p> <blockquote> <p>console.log(data &amp;&amp; data.profile &amp;&amp; data.profile.age);</p> </blockquote> <p>When translated to words it means — if <em>data</em> exists — then extract <em>data.profile </em>— and if <em>data.profile</em> exists — extract <em>data.profile.age</em></p> <p>And now we would not get an error. So problem solved? well, wait a sec!</p> <p>⚠️ Now, this is an okay workaround to solve this issue, but this gets very nasty, very fast. Just imagine if you have a deeply nested <em>object</em> and you want to access a key that is very deep into this object, how many times would you have to use the &amp;&amp; operator!</p> <p>Thus to simplify this we can now use the ES2020 <strong><em>optional chaining operator,</em></strong></p> <p><a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--0Kqpd9b8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AceKg02_1ln7CEmPWYVlIlA.png" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--0Kqpd9b8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/600/1%2AceKg02_1ln7CEmPWYVlIlA.png" alt=""></a></p> <p>Code snippet — 2.3</p> <p>In Code snippet-2.3 you can see how concise and easy to read our code is, which otherwise would have taken several lines.</p> <p>Another observation to make is that we get the output as <em>undefined</em>. Which is still much better than getting an error and now we can also handle this by merging our learning of <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator"><strong><em>Nullish coalescing ( ?? )</em></strong></a> and <a href="proxy.php?url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining"><strong><em>Optional chaining ( ?. )</em></strong></a> operator!</p> <p><strong>Comment the answer</strong> to the problem below! or <a href="proxy.php?url=https://twitter.com/vikrantbhat1022"><strong>tweet me</strong></a><strong>🐦</strong> any questions you have!</p> <p>Thanks for reading and if you liked this blog then please consider following for more posts like this!</p> javascript react tutorial beginners Redux-persist (v6) in detail (React) Vikrant Bhat Sat, 04 Jul 2020 22:00:33 +0000 https://dev.to/bhatvikrant/redux-persist-v6-in-detail-react-10nh https://dev.to/bhatvikrant/redux-persist-v6-in-detail-react-10nh <p><a href="proxy.php?url=https://i.giphy.com/media/H4buZ6PLgwsKjA9hlO/giphy.gif" class="article-body-image-wrapper"><img src="proxy.php?url=https://i.giphy.com/media/H4buZ6PLgwsKjA9hlO/giphy.gif" alt="Persistense is the key to success"></a></p> <p>Whenever you reload your app, the javascript process has nothing in memory. You will have to re-initialize state, and maybe set some basic state based on the url (if you are in a browser). Though usually this is what you want but there are many use cases where you might want to persist your redux state even when you reload your browser window.</p> <p>This idea of persisting state across refresh in web applications that use redux for global state management can be achieved using the <a href="proxy.php?url=https://www.npmjs.com/package/redux-persist">redux-persist</a> npm package.</p> <p>The complete redux-store or some specific part of it can be persisted in the browser <strong><em>localstorage</em></strong> easily!</p> <p>A very common use case for implementing redux-persist in 2020 is:</p> <blockquote> <p><strong>Offline First.</strong> Many users may not have stable internet connection. Persistence is the first step of offline support.</p> </blockquote> <p>Okay so that's it for the introduction, now let's set up redux-persist in our react-redux application.</p> <p><em>Check <a href="proxy.php?url=https://medium.com/coox-tech/how-to-setup-redux-with-react-2020-adb8cad90234">this</a> out for setting up a react-redux app</em><br> <em>or clone this <a href="proxy.php?url=https://github.com/bhatvikrant/react-redux-boilerplate">repo</a></em></p> <h2> Step 1 - Install redux-persist </h2> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>npm <span class="nb">install </span>redux-persist </code></pre> </div> <p>or<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>yarn add redux-persist </code></pre> </div> <h2> Step 2 - Configure redux-store </h2> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="c1">// store.js</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">createStore</span><span class="p">,</span> <span class="nx">applyMiddleware</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">redux</span><span class="dl">'</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">persistStore</span><span class="p">,</span> <span class="nx">persistReducer</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">redux-persist</span><span class="dl">'</span> <span class="c1">// imports from redux-persist</span> <span class="k">import</span> <span class="nx">storage</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">redux-persist/lib/storage</span><span class="dl">'</span> <span class="c1">// defaults to localStorage for web</span> <span class="k">import</span> <span class="nx">rootReducer</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./reducers</span><span class="dl">'</span> <span class="c1">// Root reducer</span> <span class="kd">const</span> <span class="nx">persistConfig</span> <span class="o">=</span> <span class="p">{</span> <span class="c1">// configuration object for redux-persist</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">root</span><span class="dl">'</span><span class="p">,</span> <span class="nx">storage</span><span class="p">,</span> <span class="c1">// define which storage to use</span> <span class="p">}</span> <span class="kd">const</span> <span class="nx">persistedReducer</span> <span class="o">=</span> <span class="nx">persistReducer</span><span class="p">(</span><span class="nx">persistConfig</span><span class="p">,</span> <span class="nx">rootReducer</span><span class="p">)</span> <span class="c1">// create a persisted reducer</span> <span class="kd">const</span> <span class="nx">store</span> <span class="o">=</span> <span class="nx">createStore</span><span class="p">(</span> <span class="nx">persistReducer</span><span class="p">,</span> <span class="c1">// pass the persisted reducer instead of rootReducer to createStore</span> <span class="nx">applyMiddleware</span><span class="p">()</span> <span class="c1">// add any middlewares here</span> <span class="p">)</span> <span class="kd">const</span> <span class="nx">persistor</span> <span class="o">=</span> <span class="nx">persistStore</span><span class="p">(</span><span class="nx">store</span><span class="p">);</span> <span class="c1">// used to create the persisted store, persistor will be used in the next step</span> <span class="k">export</span> <span class="p">{</span><span class="nx">store</span><span class="p">,</span> <span class="nx">persistor</span><span class="p">}</span> </code></pre> </div> <p>The <em>persistConfig</em> object needs <strong>key</strong> and <strong>storage</strong> to work properly since they are mandatory, but it can also take some other key value pairs for more customization, some of them are:</p> <ol> <li> <strong>blacklist:</strong> </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="nx">example</span><span class="p">:</span> <span class="c1">// BLACKLIST</span> <span class="kd">const</span> <span class="nx">persistConfig</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">root</span><span class="dl">'</span><span class="p">,</span> <span class="na">storage</span><span class="p">:</span> <span class="nx">storage</span><span class="p">,</span> <span class="na">blacklist</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">navigation</span><span class="dl">'</span><span class="p">]</span> <span class="c1">// navigation will not be persisted</span> <span class="p">};</span> </code></pre> </div> <ol> <li> <strong>whitelist:</strong> </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="nx">example</span><span class="p">:</span> <span class="c1">// WHITELIST</span> <span class="kd">const</span> <span class="nx">persistConfig</span> <span class="o">=</span> <span class="p">{</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">root</span><span class="dl">'</span><span class="p">,</span> <span class="na">storage</span><span class="p">:</span> <span class="nx">storage</span><span class="p">,</span> <span class="na">whitelist</span><span class="p">:</span> <span class="p">[</span><span class="dl">'</span><span class="s1">navigation</span><span class="dl">'</span><span class="p">]</span> <span class="c1">// only navigation will be persisted</span> <span class="p">};</span> </code></pre> </div> <blockquote> <p><strong>Note</strong>: if you are using react native then your <em>persistConfig</em> will look like this (<a href="proxy.php?url=https://github.com/rt2zz/redux-persist#v6-upgrade">see docs</a>):</p> <pre class="highlight javascript"><code><span class="k">import</span> <span class="nx">AsyncStorage</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">@react-native-community/async-storage</span><span class="dl">'</span><span class="p">;</span> <span class="kd">const</span> <span class="nx">persistConfig</span> <span class="o">=</span> <span class="p">{</span> <span class="o">&gt;</span> <span class="na">key</span><span class="p">:</span> <span class="dl">'</span><span class="s1">root</span><span class="dl">'</span><span class="p">,</span> <span class="o">&gt;</span> <span class="na">storage</span><span class="p">:</span> <span class="nx">AsyncStorage</span> <span class="o">&gt;</span><span class="p">}</span> </code></pre> </blockquote> <h2> Step 3 - Wrap your root component with <a href="proxy.php?url=https://github.com/rt2zz/redux-persist/blob/master/docs/PersistGate.md">PersistGate</a> </h2> <p>If you are using react, wrap your root component (Top level component) with PersistGate. This delays the rendering of your app's UI until your persisted state has been retrieved and saved to redux. </p> <blockquote> <p><strong>NOTE</strong> the <code>PersistGate</code>'s loading prop can alse be null, or any react instance, e.g. <code>loading={&lt;Loading /&gt;}</code> <br> i.e it can be any react component, so you can add your custom loader as a component here. <br> If null is provided as a value then it simply loads nothing until persisted state is retrieved. (Don't worry if you don't have a custom loader yet, it hardly takes fraction of a second to retrieve a simple redux state)<br> </p> </blockquote> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code><span class="k">import</span> <span class="p">{</span><span class="nx">store</span><span class="p">,</span> <span class="nx">persistor</span><span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">./redux/store</span><span class="dl">'</span> <span class="k">import</span> <span class="p">{</span> <span class="nx">PersistGate</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">redux-persist/integration/react</span><span class="dl">'</span> <span class="kd">const</span> <span class="nx">App</span> <span class="o">=</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span> <span class="o">&lt;</span><span class="nx">Provider</span> <span class="nx">store</span><span class="o">=</span><span class="p">{</span><span class="nx">store</span><span class="p">}</span><span class="o">&gt;</span> <span class="o">&lt;</span><span class="nx">PersistGate</span> <span class="nx">loading</span><span class="o">=</span><span class="p">{</span><span class="kc">null</span><span class="p">}</span> <span class="nx">persistor</span><span class="o">=</span><span class="p">{</span><span class="nx">persistor</span><span class="p">}</span><span class="o">&gt;</span> <span class="c1">// null passed to loading, persistor is being used here</span> <span class="o">&lt;</span><span class="nx">RootComponent</span> <span class="o">/&gt;</span> <span class="o">&lt;</span><span class="sr">/PersistGate</span><span class="err">&gt; </span> <span class="o">&lt;</span><span class="sr">/Provider</span><span class="err">&gt; </span> <span class="p">);</span> <span class="p">};</span> </code></pre> </div> <p><br><br> Congratulations! You have successfully completed the setup of redux-persist in your react-app! It was fairly easy wasn't it? Let me know your thoughts on <a href="proxy.php?url=https://twitter.com/vikrantbhat1022">twitter</a></p> <h3> Additional resources </h3> <blockquote> <ol> <li><p>Check out <a href="proxy.php?url=https://www.freecodecamp.org/news/how-to-use-redux-persist-when-migrating-your-states-a5dee16b5ead/">this</a> great article to know how you can do versioning in your persisted localstorage using redux-persist. This usually comes in handy when you make some big changes in your redux state and its not compatible with the previously saved localstorage in production, so redux-persist has this good to have feature for versioning built in.<br> <br><br> <a href="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--Inhx-yT2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-media-1.freecodecamp.org/images/0rJmD7xq6mgOnUokqih4WTMy2F6Kd3GmgalV" class="article-body-image-wrapper"><img src="proxy.php?url=https://res.cloudinary.com/practicaldev/image/fetch/s--Inhx-yT2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-media-1.freecodecamp.org/images/0rJmD7xq6mgOnUokqih4WTMy2F6Kd3GmgalV" alt="enter image description here"></a></p></li> <li><p><a href="proxy.php?url=https://github.com/rt2zz/redux-persist#readme">Docs</a></p></li> <li><p><a href="proxy.php?url=https://github.com/rt2zz/redux-persist#api">API</a></p></li> <li><p><a href="proxy.php?url=https://medium.com/coox-tech/how-to-setup-redux-with-react-2020-adb8cad90234">How to setup Redux with React (2020)</a></p></li> </ol> </blockquote> react redux javascript