<?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[Tadit Dash]]></title><description><![CDATA[🚀 Vice President | Author of Tech Solutions 📚 | Inspiring TEDx Speaker 🎤 | Former Microsoft MVP 🏅 | Expert in .NET, Angular, and Vue.js]]></description><link>https://blog.taditdash.com</link><generator>RSS for Node</generator><lastBuildDate>Fri, 15 May 2026 23:48:35 GMT</lastBuildDate><atom:link href="https://blog.taditdash.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Top 5 Tech Internship/Fresher Jobs Available This Week]]></title><description><![CDATA[Are you ready to jumpstart your career in the tech industry? This week, we have an exciting lineup of top internship and fresher opportunities at leading companies. Explore these roles and find the perfect fit for your skills and aspirations.
1. 💻 S...]]></description><link>https://blog.taditdash.com/top-5-tech-internshipfresher-jobs-available-this-week-1</link><guid isPermaLink="true">https://blog.taditdash.com/top-5-tech-internshipfresher-jobs-available-this-week-1</guid><category><![CDATA[fresher]]></category><category><![CDATA[internships]]></category><category><![CDATA[Freshersjobs]]></category><category><![CDATA[full stack]]></category><category><![CDATA[C#]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[golang]]></category><category><![CDATA[Angular]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Sun, 02 Jun 2024 13:56:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/B3UFXwcVbc4/upload/15cef1f44b89ca4661261672774ef219.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Are you ready to jumpstart your career in the tech industry? This week, we have an exciting lineup of top internship and fresher opportunities at leading companies. Explore these roles and find the perfect fit for your skills and aspirations.</p>
<h2 id="heading-1-software-engineer-backend-coinbase-international">1. 💻 Software Engineer, Backend - Coinbase (International)</h2>
<p><strong>Location:</strong> Remote<br /><strong>Apply</strong> <a target="_blank" href="https://www.coinbase.com/en-gb/careers/positions/5598961"><strong>here</strong></a></p>
<p>At Coinbase, we’re on a mission to increase economic freedom around the world. As a remote-first company, we're looking for talented individuals who are passionate about crypto and Web3. This role focuses on the International Payments Team, ensuring fast, reliable, and secure access to fiat payment rails globally.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li><p>Collaborate with engineers, designers, product managers, and senior leadership</p>
</li>
<li><p>Write high-quality, well-tested code</p>
</li>
<li><p>Solve large-scale, complex technical problems</p>
</li>
</ul>
<p><strong>Requirements:</strong></p>
<ul>
<li><p>Fresh graduates with a degree in Math, Stats, Physics, or Computer Science</p>
</li>
<li><p>Experience in any OO programming language (Golang, Ruby, etc.)</p>
</li>
<li><p>Willingness to learn and work on frontend code</p>
</li>
</ul>
<h2 id="heading-2-associate-developer-software-engineering-ust">2. 👨‍💻 Associate Developer - Software Engineering - UST</h2>
<p><strong>Location:</strong> Bangalore<br /><strong>Apply</strong> <a target="_blank" href="https://usource.ripplehire.com/candidate/?token=xHQWoFn4C242POo7xMpH&amp;source=CAREERSITE#detail/job/19466"><strong>here</strong></a></p>
<p>UST is seeking a full stack developer to join their team. The role involves developing and supporting existing applications with a focus on performance, quality, and responsiveness.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li><p>Ensure best possible performance of applications</p>
</li>
<li><p>Maintain code quality and organization</p>
</li>
<li><p>Design and build application layers</p>
</li>
</ul>
<p><strong>Skills:</strong></p>
<ul>
<li><p>Proficiency in C#, .NET Core, MS SQL, HTML, CSS, Angular</p>
</li>
<li><p>Knowledge of MS SQL Server and performance optimization</p>
</li>
<li><p>Understanding of code versioning tools like Git &amp; TFS</p>
</li>
</ul>
<h2 id="heading-3-trainee-nagarro">3. 🌐 Trainee - Nagarro</h2>
<p><strong>Location:</strong> Remote, India<br /><strong>Apply</strong> <a target="_blank" href="https://jobs.smartrecruiters.com/ni/Nagarro1/26076c22-eed6-47bf-a226-e819c6efb9d8-trainee"><strong>here</strong></a></p>
<p>Nagarro, a digital product engineering company, is looking for fresh talent to join their dynamic and non-hierarchical work culture. This is a fantastic opportunity to work at scale across all devices and digital mediums.</p>
<p><strong>Company Description:</strong></p>
<ul>
<li><p>Building products, services, and experiences that inspire</p>
</li>
<li><p>A team of 18,000+ experts across 36 countries</p>
</li>
</ul>
<h2 id="heading-4-software-development-engineer-i-capillary-technologies">4. 🚀 Software Development Engineer - I - Capillary Technologies</h2>
<p><strong>Location:</strong> Bengaluru<br /><strong>Apply</strong> <a target="_blank" href="https://capillarytech.skillate.com/jobs/54025"><strong>here</strong></a></p>
<p>Capillary Technologies is hiring a Software Development Engineer to join their Cloud CRM product team. The role involves developing, designing, scaling, and maintaining applications.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li><p>Develop and design scalable applications</p>
</li>
<li><p>Write effective, scalable code</p>
</li>
<li><p>Test and debug programs</p>
</li>
</ul>
<p><strong>Requirements:</strong></p>
<ul>
<li><p>0-2 years of software development experience</p>
</li>
<li><p>Strong coding and design skills in Python, Golang, NodeJs, Core Java/J2EE</p>
</li>
<li><p>Experience with Non-Relational databases is a plus</p>
</li>
</ul>
<h2 id="heading-5-graduate-engineer-trainee-jio-platforms">5. 🛠️ Graduate Engineer Trainee - Jio Platforms</h2>
<p><strong>Location:</strong> Bengaluru<br /><strong>Apply</strong> <a target="_blank" href="https://unstop.com/jobs/graduate-engineer-trainee-jio-platforms-1010568"><strong>here</strong></a></p>
<p>Jio Platforms is looking for fresh graduates to join their team as Graduate Engineer Trainees. This is a great opportunity to work with a leading telecom and digital services company.</p>
<p><strong>Responsibilities:</strong></p>
<ul>
<li><p>Develop, test, and maintain software applications</p>
</li>
<li><p>Collaborate with senior engineers on projects</p>
</li>
</ul>
<p><strong>Requirements:</strong></p>
<ul>
<li><p>Recent graduates in relevant fields</p>
</li>
<li><p>Strong problem-solving skills</p>
</li>
<li><p>Proficiency in relevant programming languages</p>
</li>
</ul>
<hr />
<p>Don't miss out on these fantastic opportunities to kickstart your career in tech! Follow <a target="_blank" href="https://www.instagram.com/taditdash/">@taditdash</a> for more job updates and career tips. DM if you need more details or job links!</p>
]]></content:encoded></item><item><title><![CDATA[Top 5 Tech Internship/Fresher Jobs Available This Week]]></title><description><![CDATA[Looking to kickstart your tech career? Here are the top 5 tech internships and fresher job opportunities available this week. These positions offer incredible opportunities to learn, grow, and make a significant impact in the tech industry. Don’t mis...]]></description><link>https://blog.taditdash.com/top-5-tech-internshipfresher-jobs-available-this-week</link><guid isPermaLink="true">https://blog.taditdash.com/top-5-tech-internshipfresher-jobs-available-this-week</guid><category><![CDATA[fresher]]></category><category><![CDATA[internships]]></category><category><![CDATA[Python]]></category><category><![CDATA[TensorFlow]]></category><category><![CDATA[SQL]]></category><category><![CDATA[React]]></category><category><![CDATA[Angular]]></category><category><![CDATA[C#]]></category><category><![CDATA[C++]]></category><category><![CDATA[AWS]]></category><category><![CDATA[full stack]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Wed, 22 May 2024 15:23:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1716391324197/0649c5d8-0bdb-4ca6-b5ba-4afe21c0384a.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Looking to kickstart your tech career? Here are the top 5 tech internships and fresher job opportunities available this week. These positions offer incredible opportunities to learn, grow, and make a significant impact in the tech industry. Don’t miss out!</p>
<h2 id="heading-1-graduate-intern-at-intel"><strong>1. Graduate Intern at Intel</strong></h2>
<p>🔗 <strong>Apply Here:</strong> <a target="_blank" href="https://jobs.intel.com/en/job/-/-/599/61709809616">Intel Graduate Intern</a><br />📍 <strong>Location:</strong> Bengaluru, Karnataka, India | Hyderabad, Telangana, India<br />📅 <strong>Job ID:</strong> JR0257947<br />🖥 <strong>Work Mode:</strong> Hybrid<br />🕒 <strong>Full/Part Time:</strong> Full Time</p>
<h3 id="heading-job-description"><strong>Job Description</strong></h3>
<p>As a Graduate Intern at Intel, you’ll be involved in a variety of technical roles, primarily focusing on semiconductor industry pre and post-silicon validation. This 1-year internship offers an excellent opportunity to gain hands-on experience in a leading tech company.</p>
<h3 id="heading-qualifications"><strong>Qualifications</strong></h3>
<ul>
<li><p><strong>Minimum:</strong> B.Tech/Bachelors in Engineering (Electronics, Electrical, Computer Science, or similar)</p>
</li>
<li><p><strong>Preferred:</strong> M.Tech/Masters in Engineering from a reputed college</p>
</li>
<li><p>Prior relevant job or internship experience is highly desired.</p>
</li>
</ul>
<h3 id="heading-benefits"><strong>Benefits</strong></h3>
<ul>
<li><p>Competitive pay, stock, bonuses</p>
</li>
<li><p>Health, retirement, and vacation benefits</p>
</li>
<li><p>Hybrid work model</p>
</li>
</ul>
<h2 id="heading-2-llm-intern-at-sony-research-india"><strong>2. LLM Intern at Sony Research India</strong></h2>
<p>🔗 <strong>Apply Here:</strong> <a target="_blank" href="https://www.linkedin.com/jobs/view/3919813125/">Sony Research India LLM Intern</a><br />📍 <strong>Location:</strong> Bengaluru, Karnataka, India (Remote/Hybrid)<br />📅 <strong>Duration:</strong> 6 months starting May 2024, full-time</p>
<h3 id="heading-job-description-1"><strong>Job Description</strong></h3>
<p>Sony Research India is seeking interns to work on cutting-edge technologies like Large Language Models (LLM), Neural Machine Translation (NMT), and more. This role is perfect for those passionate about AI and data analytics.</p>
<h3 id="heading-qualifications-1"><strong>Qualifications</strong></h3>
<ul>
<li><p>Ph.D. or Master’s in Computer Science, or Bachelor's with hands-on Python experience</p>
</li>
<li><p>Must-have skills: Pytorch, TensorFlow, scikit-learn, knowledge of LLM, RAG, RLHF-based pipeline</p>
</li>
</ul>
<h3 id="heading-values"><strong>Values</strong></h3>
<ul>
<li>Dreams &amp; Curiosity, Diversity, Integrity &amp; Sincerity, Sustainability</li>
</ul>
<h2 id="heading-3-data-intern-at-payu"><strong>3. Data Intern at PayU</strong></h2>
<p>🔗 <strong>Apply Here:</strong> <a target="_blank" href="https://jobs.eu.lever.co/payu/330d411a-955b-4545-902c-b983d44ed167">PayU Data Intern</a><br />📍 <strong>Location:</strong> Bangalore/Gurgaon/Mumbai<br />🕒 <strong>Duration:</strong> 2-12 months, full-time</p>
<h3 id="heading-job-description-2"><strong>Job Description</strong></h3>
<p>Join PayU as a Data Intern and work on science/analytics-based projects. This role involves SQL, Python, and a strong understanding of data analysis.</p>
<h3 id="heading-qualifications-2"><strong>Qualifications</strong></h3>
<ul>
<li><p>Degree in Engineering, Statistics, Computer Science, Mathematics, or similar</p>
</li>
<li><p>Excellent understanding of SQL, Python</p>
</li>
<li><p>Strong problem-solving skills and a positive attitude</p>
</li>
</ul>
<h3 id="heading-benefits-1"><strong>Benefits</strong></h3>
<ul>
<li><p>Dynamic workplace, inclusive environment</p>
</li>
<li><p>Access to over 5000 training courses</p>
</li>
</ul>
<h2 id="heading-4-software-engineer-at-netapp"><strong>4. Software Engineer at NetApp</strong></h2>
<p>🔗 <strong>Apply Here:</strong> <a target="_blank" href="https://careers.netapp.com/job/bengaluru/software-engineer/27600/65301432272">NetApp Software Engineer</a><br />📍 <strong>Location:</strong> Bengaluru, Karnataka, India<br />🖥 <strong>Job Category:</strong> Software Engineering<br />📅 <strong>Job ID:</strong> 126163-en_US</p>
<h3 id="heading-job-description-3"><strong>Job Description</strong></h3>
<p>NetApp is a cloud-led, data-centric software company. As a Software Engineer, you’ll work on innovative data management solutions and participate in the full software development lifecycle.</p>
<h3 id="heading-qualifications-3"><strong>Qualifications</strong></h3>
<ul>
<li><p>0-2 years of software development experience</p>
</li>
<li><p>Bachelor’s/Master's degree in computer science or computer engineering</p>
</li>
<li><p>Experience with AngularJS, ReactJS, REST API, Cloud, and Virtualization environments</p>
</li>
</ul>
<h3 id="heading-benefits-2"><strong>Benefits</strong></h3>
<ul>
<li><p>Comprehensive medical, dental, wellness, and vision plans</p>
</li>
<li><p>Educational assistance and financial savings programs</p>
</li>
</ul>
<h2 id="heading-5-software-developer-at-hp"><strong>5. Software Developer at HP</strong></h2>
<p>🔗 <strong>Apply Here:</strong> <a target="_blank" href="https://hp.wd5.myworkdayjobs.com/ExternalCareerSite/job/Bangalore-Karnataka-India/Software-Developer---C-C---C--WPF_3134737-2">HP Software Developer</a><br />📍 <strong>Location:</strong> Bangalore, Karnataka, India<br />🕒 <strong>Full Time</strong></p>
<h3 id="heading-job-description-4"><strong>Job Description</strong></h3>
<p>HP is seeking a Software Developer proficient in C/C++, C#, WPF. This role involves developing software systems, coding, debugging, and integrating software with existing infrastructure.</p>
<h3 id="heading-qualifications-4"><strong>Qualifications</strong></h3>
<ul>
<li><p>Four-year degree in Computer Science or related field</p>
</li>
<li><p>0-2 years of work experience</p>
</li>
<li><p>Preferred certifications: CSSE, CSEP</p>
</li>
</ul>
<h3 id="heading-skills"><strong>Skills</strong></h3>
<ul>
<li>Agile Methodology, AWS, API, Automation, Full Stack Development, Kubernetes, and more</li>
</ul>
<hr />
<p>Follow my <a target="_blank" href="https://blog.taditdash.com/newsletter">blog newsletter</a> and <a target="_blank" href="https://www.instagram.com/taditdash/">Instagram</a> for more updates on exciting job opportunities like these! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[🚀 Kickstart Your Career with MindBrain!]]></title><description><![CDATA[MindBrain is thrilled to announce walk-in interviews for two exciting positions: IT Recruiter Intern and Business Development Executive (BDE) Intern. If you have a passion for IT recruitment or business development, this is your golden opportunity!
W...]]></description><link>https://blog.taditdash.com/kickstart-your-career-with-mindbrain</link><guid isPermaLink="true">https://blog.taditdash.com/kickstart-your-career-with-mindbrain</guid><category><![CDATA[jobs]]></category><category><![CDATA[fresher]]></category><category><![CDATA[internships]]></category><category><![CDATA[Freshersjobs]]></category><category><![CDATA[Business development]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Mon, 20 May 2024 16:04:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1716220789590/1a3a9f8f-c696-4c7b-87ab-137f96a11f14.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>MindBrain is thrilled to announce walk-in interviews for two exciting positions: IT Recruiter Intern and Business Development Executive (BDE) Intern. If you have a passion for IT recruitment or business development, this is your golden opportunity!</p>
<h2 id="heading-whats-in-it-for-you"><strong>What's in it for you?</strong></h2>
<p>✨ <strong>3-month internship with a fixed stipend</strong></p>
<p>💎 <strong>Additional incentives and bonuses</strong></p>
<p>✔️ <strong>Full-time job offer post-internship with a competitive salary</strong></p>
<p>✔️ <strong>Comprehensive training provided by industry experts</strong></p>
<p>💎 <strong>Amazing career growth opportunities</strong></p>
<h2 id="heading-eligibility"><strong>Eligibility</strong></h2>
<p>📚 <strong>Students from BTech, MBA, or MCA programs</strong></p>
<p>🌟 <strong>Freshers with a keen interest in IT and business development</strong></p>
<h2 id="heading-interview-details"><strong>Interview Details</strong></h2>
<p>📅 <strong>Date:</strong> 24.05.2024</p>
<p>📍 <strong>Venue:</strong> Office No.4, 4th Floor, Indra Palace, Patia-Kalarahanga Rd, Near Patia Mo Bus Depot, Bhubaneswar, Odisha, 751024</p>
<p>Don't miss this chance to jumpstart your career with MindBrain!</p>
<hr />
<p>For the latest updates on job openings and career tips, be sure to subscribe to <a target="_blank" href="https://blog.taditdash.com/newsletter">my newsletter</a> and follow <a target="_blank" href="https://www.instagram.com/taditdash/">my Instagram</a>!🌐📸</p>
<p>Original Post</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1716221168042/72448843-2c89-4de6-82f7-714e8d2539a0.jpeg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Understanding Method Invocation Verification with Moq's Verifiable Constructs]]></title><description><![CDATA[Introduction
I encountered a scenario where I needed to test if a method inside another method was actually invoked. This led me to learn about the Verifiable construct in the Moq library. 💻 It provides a concrete way to ensure that the calls config...]]></description><link>https://blog.taditdash.com/understanding-method-invocation-verification-with-moqs-verifiable-constructs</link><guid isPermaLink="true">https://blog.taditdash.com/understanding-method-invocation-verification-with-moqs-verifiable-constructs</guid><category><![CDATA[unit testing]]></category><category><![CDATA[.NET]]></category><category><![CDATA[Moq]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Tue, 20 Feb 2024 06:12:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708409526769/5ad2fa7b-ad1c-4dba-9921-14b171f1d957.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I encountered a scenario where I needed to test if a method inside another method was actually invoked. This led me to learn about the <code>Verifiable</code> construct in the <em>Moq</em> library. 💻 It provides a concrete way to ensure that the calls configured in the mock object are indeed invoked. ℹ</p>
<h2 id="heading-example">Example 🚀</h2>
<p>Suppose a <code>CartsController</code> has a <code>CreateOrder</code> method that calls the <code>GetCartItems</code> method within it:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">CreateOrder</span>(<span class="hljs-params">OrderViewModel orderViewModel</span>)</span>
{
    <span class="hljs-keyword">var</span> cartItems = <span class="hljs-keyword">await</span> _cartService.GetCartItems(orderViewModel.CartId);

    <span class="hljs-comment">// More codes...</span>

    <span class="hljs-keyword">return</span> View(<span class="hljs-string">"OrderCreated"</span>);
}
</code></pre>
<p>A unit test for this method can be written to verify whether <code>GetCartItems</code> is actually invoked or not. Let's see how we can achieve this.</p>
<h2 id="heading-how-to-do">How to do? 🤷‍♀️</h2>
<p>Mark the mock setup for the method as <code>Verifiable</code> and then call the <code>Verify</code> method on the mock object.</p>
<p>Here is a code snippet for one unit test case:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Mock setup inside the unit test for the GetCartItems method.</span>
_cartServiceMock.Setup(x =&gt; x.GetCartItems(It.IsAny&lt;<span class="hljs-keyword">int</span>&gt;())).ReturnsAsync(() =&gt; cartItems).Verifiable();

<span class="hljs-comment">// The following CreateOrder calls the GetCartItems inside it.</span>
<span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> cartsController.CreateOrder(orderModel);

<span class="hljs-comment">// Now we can verify</span>
_cartServiceMock.Verify();
</code></pre>
<p>Notice that we set up a method <code>GetCartItems</code> to be Verifiable. Then, we called the method inside the <code>CartsController</code> to create an order. The <code>CreateOrder</code> method calls the <code>GetCartItems</code> method inside it.</p>
<p>So, <code>_cartServiceMock.Verify();</code> will now be successful as it invoked the <code>GetCartItems</code> method.</p>
<p>If for some reason it does not, then the test will throw an exception like in the following screenshot.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708334224845/49b02942-993d-480f-ac4a-1a09b044a111.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-feedback">Feedback</h2>
<p>I hope it is clear. Let me know if you have any doubts. 💪 Share, if you care. 🙌</p>
<h2 id="heading-reference">Reference</h2>
<ol>
<li><p><a target="_blank" href="https://github.com/devlooped/moq">Moq GitHub Repository</a></p>
</li>
<li><p><a target="_blank" href="https://docs.educationsmediagroup.com/unit-testing-csharp/moq/verifications">Moq Documentation on Verifications</a></p>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Insights from the "Headless and Happy Hours" Event by Hashnode]]></title><description><![CDATA[🚀When? Feb 10th, 12 PM - 4 PM📌Where? Bangalore, India
Introduction 👇
The tech world is constantly evolving, and staying updated with the latest trends and innovations is crucial for professionals in the field. 🙏
Recently, I had the opportunity to...]]></description><link>https://blog.taditdash.com/insights-from-the-headless-and-happy-hours-event-by-hashnode</link><guid isPermaLink="true">https://blog.taditdash.com/insights-from-the-headless-and-happy-hours-event-by-hashnode</guid><category><![CDATA[Hashnode]]></category><category><![CDATA[community]]></category><category><![CDATA[headless cms]]></category><category><![CDATA[Appwrite]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Fri, 09 Feb 2024 18:30:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1708170217830/990c50b9-fad5-453a-abef-2617c6061d80.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>🚀<strong>When?</strong> Feb 10th, 12 PM - 4 PM<br />📌<strong>Where?</strong> Bangalore, India</p>
<h2 id="heading-introduction">Introduction 👇</h2>
<p>The tech world is constantly evolving, and staying updated with the latest trends and innovations is crucial for professionals in the field. 🙏</p>
<p>Recently, I had the opportunity to attend the "<strong>Headless and Happy Hours</strong>" event organized by <a target="_blank" href="https://www.linkedin.com/company/hashnode/">Hashnode</a> and <a target="_blank" href="https://www.linkedin.com/company/razorpay/">Razorpay</a>, with support from <a target="_blank" href="https://www.linkedin.com/company/new-relic-inc-/">New Relic</a> and DigitalOcean. 🌊</p>
<p>The event proved to be an enlightening experience, offering insights into the headless architecture, backend as a service features, innovative notification solutions, and invaluable networking opportunities. 🤝🍻</p>
<h2 id="heading-exploring-headless-architecture">Exploring Headless Architecture 🤯</h2>
<p>One of the highlights of the event was delving into the world of headless architecture by Mr <a class="user-mention" href="https://hashnode.com/@atapas">Tapas Adhikary</a>. Hashnode, renowned for its user-friendly platform for building blogs, showcased its <a target="_blank" href="https://hashnode.com/headless">headless</a> approach, which allows developers to create and scale blog sites with ease.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708169485839/d2e1ea66-2a34-4348-8c39-3bb39e452418.gif" alt class="image--center mx-auto" /></p>
<p>The session shed light on the advantages of adopting a headless approach, offering flexibility and scalability while maintaining a seamless user experience. 😎</p>
<h2 id="heading-backend-as-a-service-with-appwrite">Backend as a Service with Appwrite</h2>
<p>Mr <a class="user-mention" href="https://hashnode.com/@adityaoberai">Aditya Oberai</a>, a distinguished speaker at the event, provided valuable insights into the backend as a service feature offered by <a target="_blank" href="https://www.linkedin.com/company/appwrite/">Appwrite</a>. 🎉</p>
<p>His presentation highlighted the capabilities of Appwrite in simplifying backend development tasks, empowering developers to focus more on building innovative front-end experiences. 🐥</p>
<p>The discussion underscored the importance of leveraging efficient backend solutions in modern application development workflows. ⚒️</p>
<h2 id="heading-innovative-notification-solutions">Innovative Notification Solutions 🔔</h2>
<p>Another intriguing aspect of the event was the introduction of <em>Novu</em>, a cutting-edge notification solution presented by Mr. <a class="user-mention" href="https://hashnode.com/@sumitsaurabh927">Sumit Saurabh</a>. 👋</p>
<p><em>Novu</em> promises to revolutionize developer workflows by offering seamless and customizable notification functionalities. The presentation sparked curiosity among attendees, showcasing the potential of Novu to enhance user engagement and drive platform growth.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1708169925237/d445b4ab-0e57-427c-89bb-74e7e8b76106.gif" alt class="image--center mx-auto" /></p>
<h2 id="heading-networking-and-insights">Networking and Insights</h2>
<p>Beyond the informative sessions, the event provided ample networking opportunities with industry leaders and fellow enthusiasts. Meeting Mr. <a class="user-mention" href="https://hashnode.com/@skipiit">Subhendu Panigrahi</a> proved to be a highlight, as his insights into entrepreneurship and clarifications on various technical queries enriched the learning experience. 📚</p>
<p>Additionally, interactions with Mr. <a class="user-mention" href="https://hashnode.com/@atapas">Tapas Adhikary</a> and Mr. Sandeep Panda about potential product ideas with the collaborative spirit of the tech community. 🤝</p>
<h2 id="heading-engaging-conversations">Engaging Conversations</h2>
<p>Engaging conversations with <a class="user-mention" href="https://hashnode.com/@Ishikkkkaaaa">Ishika kesarwani</a> provided valuable insights into community activities, developer relations, and software development practices. 👌</p>
<h2 id="heading-lets-meet-up">Let's meet up!</h2>
<p>This does not stop here. I will be attending more events in the future to network with techies and learn from them.</p>
<p>Let's meet and discuss. 🙂</p>
]]></content:encoded></item><item><title><![CDATA[Serverless on Azure: A Recap of the Event]]></title><description><![CDATA[Last Saturday, I had the opportunity to attend a fantastic event on Serverless on Azure, organized by Experis - A Manpower company. The event was held at Experis, Tower C, 7th floor, IBC Knowledge Park, Bhavani Nagar, SG Palya, Bannerghatta Main Road...]]></description><link>https://blog.taditdash.com/serverless-on-azure-a-recap-of-the-event</link><guid isPermaLink="true">https://blog.taditdash.com/serverless-on-azure-a-recap-of-the-event</guid><category><![CDATA[Azure]]></category><category><![CDATA[serverless]]></category><category><![CDATA[Experis]]></category><category><![CDATA[BDotnet]]></category><category><![CDATA[Manpower]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Mon, 21 Aug 2023 16:46:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1692636270948/72dcf675-43ee-4161-bd65-daceb05cba5f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Last Saturday, I had the opportunity to attend a fantastic event on Serverless on Azure, organized by Experis - A Manpower company. The event was held at <em>Experis, Tower C, 7th floor, IBC Knowledge Park, Bhavani Nagar, SG Palya, Bannerghatta Main Road, Bangalore 560029</em> and featured four speakers who shared their insights and experiences on building serverless applications on Azure. Here are some of the highlights from the event.</p>
<h2 id="heading-about-experis">About Experis 🏢</h2>
<p>The event started with an introduction by <em>Sriram Ramakrishnan, Sr. Practice VP at Experis</em>, and <em>Patrick Mclnenly, Enterprise Delivery Director at Experis</em>. They talked about the vision and mission of Experis, which is to provide innovative solutions and talent for the digital age.</p>
<p>They also explained how Experis helps clients leverage serverless technologies to achieve scalability, agility, and cost-efficiency.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634680319/1cf5f90c-1ac3-462e-a348-4db7a666ef51.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-architecting-serverless-applications-on-azure">Architecting Serverless applications on Azure 🛠️</h2>
<p>The first technical session was delivered by Karthikeyan VK, CTO at PROIndia and Microsoft MVP. He gave an overview of the serverless architecture and its benefits, such as reduced operational overhead, faster time to market, and pay-per-use pricing.</p>
<p>He also demonstrated how to design and implement serverless applications on Azure using various services, such as Azure Functions, Event Grid, and Cosmos DB.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634621736/256f8028-ef60-4f9f-99d0-25e49283045c.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-building-serverless-net-applications-on-azure">Building Serverless .NET applications on Azure 💻</h2>
<p>The next session was presented by <em>Aditya Oberai, Developer Advocate at Appwrite and Microsoft MVP</em>. He focused on how to build serverless .NET applications on Azure using C#, Visual Studio, and Azure DevOps.</p>
<p>He showed how to create, test, debug, and deploy Azure Functions using different triggers and bindings.</p>
<p>He also shared some best practices and tips for optimizing the performance and security of serverless .NET applications.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634737194/119fa217-0988-4ff1-896d-16f75e495800.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-wrap-upgoodiesclosing-note">Wrap up/Goodies/Closing note 🎁</h2>
<p>The event concluded with a wrap-up by <em>Sriram and Pat</em>, who thanked the speakers, the audience, and the sponsors for making the event a success. They also distributed some goodies to the attendees, such as water bottles with the Experis logo. I was lucky enough to get one of them!</p>
<h2 id="heading-my-takeaways">My takeaways 🙌</h2>
<p>I really enjoyed attending the event and learned a lot about serverless on Azure. I also got to network with some fantastic people who share my passion for technology. I would like to thank <em>Experis</em> for organizing this event and giving me this opportunity. I would also like to congratulate the <em>BDotnet</em> User Group and specially <em>Swaminathan Vetri</em> for coordinating this event. I look forward to attending more events like this in the future.</p>
<p>One of the best moments of the event was when I got a signed copy of <em>Karthikeyan’s book “Developers Road Ahead”</em>. It is a great book that covers various topics related to software development and career growth. I can’t wait to read it!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692636206047/e5622c1e-645f-4307-9a06-82d915350992.jpeg" alt class="image--center mx-auto" /></p>
<h1 id="heading-gallery">Gallery</h1>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634796475/da053bbc-1a3a-44ce-825e-b9ac71ddc9c7.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634819598/7182c169-79c3-45ef-8cd4-ee762cebd536.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634846886/fa894bbe-6209-4b8b-a599-672fb30d0495.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634881560/22f6eca3-dca9-4431-a686-b32569220818.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634906935/d0389179-c710-437c-bd6b-7113d7c02ae9.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1692634931535/9244c98a-0505-4d9a-8d8b-d9b14fd56cb6.jpeg" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[How to Use the New Simplified Output Path Feature in .NET 8 🚀]]></title><description><![CDATA[Introduction
One of the new features in .NET 8 is the option to simplify the output path and folder structure for build outputs. In this blog, I’ll explain what this feature is, why it is useful, and how to use it. At the time of writing this blog, I...]]></description><link>https://blog.taditdash.com/how-to-use-the-new-simplified-output-path-feature-in-net-8</link><guid isPermaLink="true">https://blog.taditdash.com/how-to-use-the-new-simplified-output-path-feature-in-net-8</guid><category><![CDATA[.NET]]></category><category><![CDATA[build]]></category><category><![CDATA[.net 8]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Mon, 07 Aug 2023 17:05:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1691376589044/f28f77b4-de87-4b7a-8cc8-a9fbd36731fc.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>One of the new features in .NET 8 is the option to simplify the output path and folder structure for build outputs. In this blog, I’ll explain what this feature is, why it is useful, and how to use it. At the time of writing this blog, I am using the <em>.NET 8 SDK Version - 8.0.100-preview.6.23330.14</em>.</p>
<h2 id="heading-what-is-the-output-path">What is the output path? 📂</h2>
<p>The output path is the location where the build artifacts of your .NET application are stored. Build artifacts include compiled assemblies, configuration files, dependencies, symbols, and other files that are needed to run or debug your application.</p>
<h2 id="heading-what-was-the-problem-with-the-previous-output-path-structure">What was the problem with the previous output path structure? ❌</h2>
<p>Previously, .NET applications produced a deep and complex set of output paths for different build artifacts.</p>
<p><em>For example,</em> if you had a .NET Core console app named <em>MyApp</em>, targeting netcoreapp3.1 and net5.0 frameworks, and built it in Debug mode, you would get something like this:</p>
<pre><code class="lang-powershell">MyApp
├── bin
│   ├── Debug
│   │   ├── netcoreapp3.<span class="hljs-number">1</span>
│   │   │   ├── MyApp.dll
│   │   │   ├── MyApp.pdb
│   │   │   ├── MyApp.runtimeconfig.dev.json
│   │   │   ├── MyApp.runtimeconfig.json
│   │   │   └── MyApp.deps.json
│   │   └── net5.<span class="hljs-number">0</span>
│   │       ├── MyApp.dll
│   │       ├── MyApp.pdb
│   │       ├── MyApp.runtimeconfig.dev.json
│   │       ├── MyApp.runtimeconfig.json
│   │       └── MyApp.deps.json
└── obj
    ├── Debug
    │   ├── netcoreapp3.<span class="hljs-number">1</span>
    │   │   ├── MyApp.AssemblyInfo.cs
    │   │   ├── MyApp.AssemblyInfoInputs.cache
    │   │   ├── MyApp.assets.cache
    │   │   ├── MyApp.csproj.FileListAbsolute.txt
    │   │   └── project.assets.json
    │   └── net5.<span class="hljs-number">0</span>
    │       ├── MyApp.AssemblyInfo.cs
    │       ├── MyApp.AssemblyInfoInputs.cache
    │       ├── MyApp.assets.cache
    │       ├── MyApp.csproj.FileListAbsolute.txt
    │       └── project.assets.json
    └── project.nuget.cache
</code></pre>
<p>As you can see, this structure is quite verbose and redundant. It also has some drawbacks, such as:</p>
<ul>
<li><p>It makes it harder to find and manage the output files, especially if you have a large solution with many projects and target frameworks.</p>
</li>
<li><p>It increases the size of the output folder, as it contains duplicate files for shared dependencies across different target frameworks.</p>
</li>
<li><p>It slows down the build process, as it requires copying files across different subfolders.</p>
</li>
</ul>
<h2 id="heading-how-does-the-new-output-path-structure-simplify-things">How does the new output path structure simplify things? ✅</h2>
<p>The new output path structure gathers all build outputs into a common location, which makes it easier for tooling to anticipate. It also reduces the verbosity and redundancy of the previous structure.</p>
<p>To opt into the new output path format, you need to run the following command in order to create the <em>Directory.Build.props</em> file.</p>
<p><code>dotnet new buildprops --use-artifacts</code></p>
<p><em>For example,</em> if you enable the simplified output path feature for the same <em>MyApp</em> console app using the command above, you would get something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1691374923061/ef99b31c-26a6-427b-b16e-7cf9de43caa2.png" alt="Simplified Output Path Feature - .NET 8" class="image--center mx-auto" /></p>
<p>The directory listing tree will be something similar to the following.</p>
<pre><code class="lang-powershell">MyApp
├───artifacts
│   ├───bin
│   │   └───MyApp
│   │       └───debug
│   │               MyApp.deps.json
│   │               MyApp.dll
│   │               MyApp.exe
│   │               MyApp.pdb
│   │               MyApp.runtimeconfig.json
│   └───obj
│       └───MyApp
│           │   MyApp.csproj.nuget.dgspec.json
│           │   MyApp.csproj.nuget.g.props
│           │   MyApp.csproj.nuget.g.targets
│           │   project.assets.json
│           │   project.nuget.cache
│           │
│           └───debug
│               │   .NETCoreApp,Version=v8.<span class="hljs-number">0</span>.AssemblyAttributes.cs
│               │   apphost.exe
│               │   MyApp.AssemblyInfo.cs
│               │   ...
</code></pre>
<p>Essentially, it created an <em>artifacts</em> directory under the <em>MyApp</em> directory and generated all build files inside that. You can customize the path by editing the property <code>ArtifactsPath</code> in <em>Directory.Build.props</em> file.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Project</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- See https://aka.ms/dotnet/msbuild/customize for more details on customizing your build --&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ArtifactsPath</span>&gt;</span>$(MSBuildThisFileDirectory)artifacts<span class="hljs-tag">&lt;/<span class="hljs-name">ArtifactsPath</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Project</span>&gt;</span>
</code></pre>
<p>As you can see, this structure is much simpler and cleaner. It also has some benefits, such as:</p>
<ul>
<li><p>It makes it easier to find and manage the output files, as they are all in one place.</p>
</li>
<li><p>It reduces the size of the output folder, as it eliminates duplicate files for shared dependencies across different target frameworks.</p>
</li>
<li><p>It speeds up the build process, as it avoids copying files across different subfolders.</p>
</li>
</ul>
<p>Once you have enabled the simplified output path feature, you can use it as usual. You can build your solution, run your projects, debug them, test them, and deploy them. The only difference is that all your output files will be in the same folder.</p>
<p>You can also use the simplified output path feature with other features and tools that work with .NET 8, such as:</p>
<ul>
<li><p><strong>Publishing</strong>: You can publish your projects to various platforms and destinations using the <code>dotnet publish</code> command or the Publish tool in Visual Studio. The published files will be placed in the same output folder as well.</p>
</li>
<li><p><strong>Packaging</strong>: You can package your projects into NuGet packages using the <code>dotnet pack</code> command or the Pack tool in Visual Studio. The package files will be placed in the same output folder as well.</p>
</li>
<li><p><strong>Testing</strong>: You can run your tests using the <code>dotnet test</code> command or the Test Explorer in Visual Studio. The test results will be placed in the same output folder as well.</p>
</li>
<li><p><strong>Code analysis</strong>: You can run code analysis tools such as Roslyn analyzers or StyleCop on your projects using the <code>dotnet analyze</code> command or the Code Analysis tool in Visual Studio. The analysis results will be placed in the same output folder as well.</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion 🎉</h2>
<p>The simplified output path feature is a new option that you can enable in .NET 8 to specify a single output path for all your projects. This can make your development workflow simpler, more organized, faster, and more compatible with other features and tools.</p>
<p>I hope you found this blog helpful and informative. If you have any questions or feedback, please leave a comment below.</p>
]]></content:encoded></item><item><title><![CDATA[Demystifying the Deployment of a .NET 6 Application on Windows Server with IIS 🚀]]></title><description><![CDATA[Introduction
📝 Deploying a .NET 6 application on a Windows server with IIS can be a thrilling yet challenging task. In this blog post, we will explore the steps our team followed, the hurdles we encountered, and the solution that ultimately led to s...]]></description><link>https://blog.taditdash.com/demystifying-the-deployment-of-a-net-6-application-on-windows-server-with-iis</link><guid isPermaLink="true">https://blog.taditdash.com/demystifying-the-deployment-of-a-net-6-application-on-windows-server-with-iis</guid><category><![CDATA[.net 6.0]]></category><category><![CDATA[deployment]]></category><category><![CDATA[Web API]]></category><category><![CDATA[IIS]]></category><category><![CDATA[Hosting Bundle]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Mon, 24 Jul 2023 08:51:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/rUTpMpG6GEQ/upload/96d1416ffa2521fa5d159e4e515a93d1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>📝 Deploying a .NET 6 application on a Windows server with IIS can be a thrilling yet challenging task. In this blog post, we will explore the steps our team followed, the hurdles we encountered, and the solution that ultimately led to success.</p>
<p>Join me on this journey as we unravel the mystery of the elusive <em>"HTTP Error 500.31 - Failed to load</em> <a target="_blank" href="http://ASP.NET"><em>ASP.NET</em></a> <em>Core runtime." 🕵️‍♂️</em></p>
<h1 id="heading-deployment-steps">Deployment Steps 📢</h1>
<p>Let's look at the high-level steps that we followed to build and deploy the .NET 6 WebAPI.</p>
<h2 id="heading-step-1-installing-the-latest-aspnethttpaspnet-core-hosting-bundle">Step 1: Installing the Latest <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core Hosting Bundle 💻</h2>
<p>The first step we took was installing the essential <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core Hosting bundle from Microsoft Official. At the time of our deployment, .NET 7 was the latest, and we downloaded the bundle from the <a target="_blank" href="https://dotnet.microsoft.com/en-us/download/dotnet/7.0">link</a>.</p>
<p>Take a look at the screenshot below highlighting the Hosting Bundle area.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689754663869/d0933e7d-38e4-4b7a-b17a-571810291d18.png" alt="Downloading the ASP.NET Core Hosting Bundle 7.0" class="image--center mx-auto" /></p>
<h2 id="heading-step-2-publishing-the-net-6-webapi-project">Step 2: Publishing the .NET 6 WebAPI Project 🚀</h2>
<p>With the Hosting Bundle installed on our local machine, we proceeded to publish the .NET 6 WebAPI project as a framework-dependent build. This process ensures that the application will run seamlessly on the target server.</p>
<p>Check out the screenshot below to get a glimpse of the publish settings.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1690188163530/ea4bef25-5981-400d-b23c-08a24f1b185e.png" alt="Framework Dependent Deployment Mode .NET" class="image--center mx-auto" /></p>
<h2 id="heading-step-3-moving-artefacts-to-the-windows-server">Step 3: Moving Artefacts to the Windows Server 📂</h2>
<p>Once the build artefacts were generated, we transferred them to the Windows Server, preparing for the deployment process.</p>
<h2 id="heading-step-4-iis-configuration-and-application-pool-setup">Step 4: IIS Configuration and Application Pool Setup ⚙️</h2>
<p>To deploy the application, we followed the typical IIS steps, creating a new Application Pool with the .NET CLR version set to "<em>No Managed Code</em>". This configuration is crucial for running .NET Core applications in IIS.</p>
<p>Have a look at the screenshot below for an example of this setup.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689755585299/d9513c76-9bf1-4b72-83d9-c9fbad8c9742.png" alt="IIS Application Pool No Managed Code" class="image--center mx-auto" /></p>
<h1 id="heading-encountering-the-mysterious-http-error-50031">Encountering the Mysterious HTTP Error 500.31 ❓</h1>
<p>Despite our meticulous preparation, we faced an unexpected roadblock when browsing the application from IIS. The dreaded "HTTP Error 500.31 - Failed to load <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core runtime" message appeared, leaving us puzzled. The Hosting Bundle installation should have included the necessary runtime, but it seemed unclear why it failed.</p>
<p>Here is the screenshot of the error from the browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689755005489/fd0b7c21-ea29-4a8e-ad2b-c2048901bcc3.jpeg" alt="HTTP Error 500.31" class="image--center mx-auto" /></p>
<h1 id="heading-unravelling-the-solution">Unravelling the Solution 💡</h1>
<p>Undeterred, we launched into extensive research and tried various approaches involving the Application Pool and IIS settings, but to no avail. It wasn't until we stumbled upon online discussions about the Hosting Bundle's backward compatibility that we gained a breakthrough.</p>
<h1 id="heading-the-missing-piece-aspnethttpaspnet-hosting-bundle-6">The Missing Piece <a target="_blank" href="http://ASP.NET">ASP.NET</a> Hosting Bundle 6 ✨</h1>
<p>After multiple trials and errors, we finally achieved success by installing the <a target="_blank" href="http://ASP.NET">ASP.NET</a> Hosting Bundle 6. This seemingly simple step proved to be the key that unlocked the solution, resolving the enigmatic HTTP Error 500.31.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1689754750906/79c76769-c712-4cb4-8918-6ed96857350c.png" alt="Downloading the ASP.NET Core Hosting Bundle 6.0" class="image--center mx-auto" /></p>
<h1 id="heading-conclusion">Conclusion</h1>
<p>Our journey to deploy a .NET 6 application on a Windows Server with IIS was a rollercoaster of challenges and discoveries. By sharing my experiences and uncovering the importance of using the compatible Hosting Bundle, I hope to save you from similar headaches during your own deployments.</p>
<h1 id="heading-feedback">🌟 Feedback</h1>
<p>I'd love to hear your thoughts! Leave a comment below if you found this blog post helpful or if you have any questions.</p>
<p>Happy deploying! 😊</p>
]]></content:encoded></item><item><title><![CDATA[🔒🛡️ Demystifying Angular 16 Route Guard 🛡️🔒]]></title><description><![CDATA[Welcome back, fellow Angular enthusiasts! Today, we're diving into the intriguing world of Angular 16 Route Guards. 🚀
💡 Introduction💡
Angular 16 Route Guards are powerful tools that help us control navigation and access to specific routes in our A...]]></description><link>https://blog.taditdash.com/demystifying-angular-16-route-guard</link><guid isPermaLink="true">https://blog.taditdash.com/demystifying-angular-16-route-guard</guid><category><![CDATA[Angular]]></category><category><![CDATA[routing]]></category><category><![CDATA[angular16]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Sat, 08 Jul 2023 07:48:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1688802308645/84f8b1aa-be87-4a7c-bf96-0feb08d9502e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome back, fellow Angular enthusiasts! Today, we're diving into the intriguing world of Angular 16 Route Guards. 🚀</p>
<h1 id="heading-introduction">💡 Introduction💡</h1>
<p>Angular 16 Route Guards are powerful tools that help us control navigation and access to specific routes in our Angular 16 applications. With these guards, we can protect certain routes from unauthorized access or perform additional checks before allowing users to proceed. One such guard we'll explore today is the ProductDetailGuard. Let's unravel its secrets! 🕵️‍♂️</p>
<h1 id="heading-background">🔍 Background 🔍</h1>
<p>My use case is very simple and it mimics a real application use case. Here it is.</p>
<ul>
<li><p><code>ProductDetail</code> Component will only load if the URL contains a <code>ProductId &gt; 0</code></p>
</li>
<li><p>Anything else will be rejected and redirected to <code>Product</code> Component</p>
</li>
</ul>
<p>Let's explore the code!</p>
<h1 id="heading-the-productdetailguard-code">🔐 The ProductDetailGuard Code 🔐</h1>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { inject } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/core'</span>;
<span class="hljs-keyword">import</span> { CanActivateFn, Router } <span class="hljs-keyword">from</span> <span class="hljs-string">'@angular/router'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> ProductDetailGuard: CanActivateFn = <span class="hljs-function">(<span class="hljs-params">route, state</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">Number</span>(route.paramMap.get(<span class="hljs-string">'id'</span>)) &gt; <span class="hljs-number">0</span>
    ? <span class="hljs-literal">true</span>
    : inject(Router).createUrlTree([<span class="hljs-string">'/products'</span>]);
};
</code></pre>
<p>In the code snippet above, we define the <code>ProductDetailGuard</code> as a <code>CanActivateFn</code>. This type of guard is responsible for determining whether a user can activate (access) a particular route.</p>
<p>The guard function receives two parameters: <code>route</code> and <code>state</code>. The <code>route</code> parameter contains information about the current route, while <code>state</code> provides details about the router state.</p>
<h2 id="heading-guarding-the-product-detail-route">🚧 Guarding the Product Detail Route 🚧</h2>
<p>The purpose of our <code>ProductDetailGuard</code> is to protect the route that displays detailed information about a product. It ensures that the user can only access the route if the <code>ProductId</code> provided in the route parameters is a positive number (<code>Number(route.paramMap.get('id')) &gt; 0</code>).</p>
<p>If the condition is met, the guard returns <code>true</code>, allowing the user to proceed to the desired route.</p>
<h2 id="heading-redirecting-unauthorized-users">⛔ Redirecting Unauthorized Users ⛔</h2>
<p>On the other hand, if the condition evaluates to <code>false</code>, indicating an invalid or unauthorized access attempt, the guard takes action.</p>
<p>It uses the <code>inject</code> function from <code>@angular/core</code> to access the Angular injector and retrieve an instance of the <code>Router</code>.</p>
<p>With the <code>Router</code> instance in hand, it creates a URL tree using <code>createUrlTree(['/products'])</code>. This URL tree represents the desired destination, in this case, the <code>/products</code> route.</p>
<p>By returning the URL tree, the guard effectively redirects unauthorized users back to the products listing page.</p>
<h1 id="heading-putting-the-guard-into-action">🛡️ Putting the Guard into Action 🛡️</h1>
<p>To activate our <code>ProductDetailGuard</code>, we need to integrate it into our application's routing configuration. Within the route definition for the product detail route, we can assign the guard using the <code>canActivate</code> property. For example:</p>
<pre><code class="lang-typescript">{
  path: <span class="hljs-string">'products/:id'</span>,
  component: ProductDetailComponent,
  canActivate: [ProductDetailGuard]
}
</code></pre>
<p>By attaching the <code>ProductDetailGuard</code> to the <code>canActivate</code> property, we ensure that the guard is invoked before allowing access to the <code>ProductDetailComponent</code>.</p>
<p>This way, we add an extra layer of security to our application, safeguarding the product detail page from unauthorized users.</p>
<h1 id="heading-strengthen-your-angular-application-with-route-guards">🔒🔓 Strengthen Your Angular Application with Route Guards 🔓🔒</h1>
<p>Route guards are an essential part of building secure and robust Angular applications. With guards like the <code>ProductDetailGuard</code>, we can control access to routes, protect sensitive information, and guide users towards the appropriate sections of our application.</p>
<p>By leveraging these powerful tools, we enhance the user experience and ensure that our application remains reliable and trustworthy.</p>
<p>So, next time you find yourself needing to restrict access to certain routes or perform additional checks before allowing navigation, remember to employ Angular 16 Route Guards. Your application and your users will thank you! 💪</p>
<h1 id="heading-feedback">📝🗣️ Feedback! 🗣️📝</h1>
<p>I would greatly appreciate your feedback on this blog post! Please take a moment to share your thoughts, suggestions, or any questions you may have in the comments below. Your feedback is incredibly valuable to me as it helps me improve and provide you with even better content in the future. Thank you for your support and for taking the time to share your input!</p>
]]></content:encoded></item><item><title><![CDATA[Focusing on the First Invalid Field in a DevExtreme Tab Panel Component: A Hack Explained]]></title><description><![CDATA[Introduction
In this blog post, we will explore a code snippet that addresses the issue of focusing on the first invalid field within a tab control component of the DevExtreme library in an Angular application. The code provides a workaround to handl...]]></description><link>https://blog.taditdash.com/focusing-on-the-first-invalid-field-in-a-devextreme-tab-panel-component-a-hack-explained</link><guid isPermaLink="true">https://blog.taditdash.com/focusing-on-the-first-invalid-field-in-a-devextreme-tab-panel-component-a-hack-explained</guid><category><![CDATA[Angular]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Validation]]></category><category><![CDATA[DevExpress]]></category><category><![CDATA[TabPanel]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Sat, 10 Jun 2023 15:17:17 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686410004607/a1ea4c45-d9fc-4f43-b151-63299e16e447.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-introduction">Introduction</h1>
<p>In this blog post, we will explore a code snippet that addresses the issue of focusing on the first invalid field within a tab control component of the DevExtreme library in an Angular application. The code provides a workaround to handle validation errors and ensures that the user's attention is immediately drawn to the first field that requires correction.</p>
<h1 id="heading-code-explanation">Code Explanation</h1>
<p>Let's dissect the code step by step to understand how it achieves the desired behavior.</p>
<pre><code class="lang-typescript">focusOnInvalidTabAndField() {
  <span class="hljs-keyword">const</span> brokenRules: <span class="hljs-built_in">any</span> = <span class="hljs-built_in">this</span>.validationGroup.instance.validate().brokenRules;
  <span class="hljs-keyword">if</span> (brokenRules &amp;&amp; brokenRules.length &gt; <span class="hljs-number">0</span>) {
    <span class="hljs-comment">// Find the closest dx-item.</span>
    <span class="hljs-keyword">const</span> closestTab = brokenRules[<span class="hljs-number">0</span>].validator._$element[<span class="hljs-number">0</span>].closest(<span class="hljs-string">'.dx-multiview-item-content'</span>);
</code></pre>
<ol>
<li><p>The function <code>focusOnInvalidTabAndField()</code> is a custom method responsible for focusing on the first invalid field within the tab panel.</p>
</li>
<li><p>The <code>validate()</code> method is invoked on the <code>validationGroup.instance</code>, which presumably refers to the instance of the validation group associated with the tab panel component. It returns an object containing the broken validation rules.</p>
</li>
<li><p>The <code>brokenRules</code> variable is assigned the <code>brokenRules</code> property of the validation result, allowing us to access the list of broken rules.</p>
</li>
</ol>
<pre><code class="lang-typescript">    <span class="hljs-keyword">if</span> (closestTab) {
      <span class="hljs-comment">// Get the tab index of the closest tab panel.</span>
      <span class="hljs-keyword">const</span> tabIndex = closestTab.dataset.tabItemIndex;
</code></pre>
<ol>
<li><p>The code checks if the <code>closestTab</code> exists. If an invalid field is found, the <code>closestTab</code> refers to the DOM element associated with the tab panel that contains the invalid field.</p>
</li>
<li><p>The <code>tabIndex</code> variable is assigned the value of the <code>tabItemIndex</code> attribute from the <code>dataset</code> property of the <code>closestTab</code> element. This attribute presumably stores the index of the tab panel.</p>
</li>
</ol>
<pre><code class="lang-typescript">      <span class="hljs-comment">// Select the found panel.</span>
      <span class="hljs-built_in">this</span>.selectedTabIndex = tabIndex;
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.model.main.Headerbutton) {
        <span class="hljs-built_in">this</span>.selectedHeaderButtonTabIndex = tabIndex;
      }
</code></pre>
<ol>
<li><p>The code updates the <code>selectedTabIndex</code> property to the value stored in <code>tabIndex</code>, which effectively changes the selected tab panel to the one containing the first invalid field.</p>
</li>
<li><p>Additionally, if the condition <code>this.model.main.Headerbutton</code> evaluates to true, it updates the <code>selectedHeaderButtonTabIndex</code> property with the same value. This step might be specific to the application's logic and can be ignored if not applicable.</p>
</li>
</ol>
<pre><code class="lang-typescript">      <span class="hljs-comment">// Focus the first error field.</span>
      brokenRules[<span class="hljs-number">0</span>].validator.focus();
    }
  }
}
</code></pre>
<ol>
<li>Finally, the <code>focus()</code> method is invoked on the <code>validator</code> property of the first item in the <code>brokenRules</code> array. This method triggers the focus on the first invalid field, bringing it into the user's immediate attention.</li>
</ol>
<h1 id="heading-conclusion">Conclusion</h1>
<p>The provided code snippet demonstrates a practical solution to focus on the first invalid field within a DevExtreme tab panel component. By utilizing the broken validation rules and leveraging the DOM manipulation capabilities, the code effectively selects the tab panel containing the invalid field and brings it into view, allowing the user to easily identify and address the validation error.</p>
<p>Please note that this code snippet assumes the presence of specific properties and elements (<code>validationGroup</code>, <code>instance</code>, <code>model.main.Headerbutton</code>, etc.) in the surrounding codebase, and it may require adjustments to fit different scenarios.</p>
<h1 id="heading-full-code-snippet">Full Code Snippet</h1>
<pre><code class="lang-javascript">focusOnInvalidTabAndField() {
    <span class="hljs-keyword">const</span> brokenRules: any = <span class="hljs-built_in">this</span>.validationGroup.instance.validate().brokenRules;
    <span class="hljs-keyword">if</span> (brokenRules &amp;&amp; brokenRules.length &gt; <span class="hljs-number">0</span>) {
      <span class="hljs-comment">// Find the closest dx-item.</span>
      <span class="hljs-keyword">const</span> closesetTab = brokenRules[<span class="hljs-number">0</span>].validator._$element[<span class="hljs-number">0</span>].closest(<span class="hljs-string">'.dx-multiview-item-content'</span>);
      <span class="hljs-keyword">if</span> (closesetTab) {
        <span class="hljs-comment">// Get the tab index of the closest tab panel.</span>
        <span class="hljs-keyword">const</span> tabIndex = closesetTab.dataset.tabItemIndex;
        <span class="hljs-comment">// Select the found panel.</span>
        <span class="hljs-built_in">this</span>.selectedTabIndex = tabIndex;
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.model.main.Headerbutton) {
          <span class="hljs-built_in">this</span>.selectedHeaderButtonTabIndex = tabIndex;
        }
        <span class="hljs-comment">// Focus the first error field.</span>
        brokenRules[<span class="hljs-number">0</span>].validator.focus();
      }
    }
  }
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Designing Software with Empathy: Inclusive Development for All Users]]></title><description><![CDATA[Introduction🙏
In today's interconnected world, software developers have the power to create applications that touch the lives of people from all walks of life. It is crucial for developers to approach their work with empathy, ensuring that their sof...]]></description><link>https://blog.taditdash.com/designing-software-with-empathy-inclusive-development-for-all-users</link><guid isPermaLink="true">https://blog.taditdash.com/designing-software-with-empathy-inclusive-development-for-all-users</guid><category><![CDATA[software development]]></category><category><![CDATA[Accessibility]]></category><category><![CDATA[User Research]]></category><category><![CDATA[user experience]]></category><category><![CDATA[Design]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Fri, 09 Jun 2023 10:22:52 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686303212858/c5f0b96a-9f49-4a8a-b9a9-35419149a8ed.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction🙏</h2>
<p>In today's interconnected world, software developers have the power to create applications that touch the lives of people from all walks of life. It is crucial for developers to approach their work with empathy, ensuring that their software is accessible and inclusive for users regardless of their profession, education level, or background.</p>
<p>In this article, we will explore the importance of designing software with care, paying special attention to the needs and behaviours of users from diverse backgrounds.</p>
<p>By incorporating user research and interviews into the development process, developers can create software that truly caters to the needs of every user, including those who may be less educated or work in unconventional professions.</p>
<h2 id="heading-understanding-user-diversity">Understanding User Diversity 🤔</h2>
<p>Users of software applications come from diverse backgrounds, professions, and educational levels. As developers, it is our responsibility to recognize and respect this diversity.</p>
<p>Every user should be able to navigate and utilize software seamlessly, regardless of their <strong>educational background</strong> or <strong>profession</strong>.</p>
<p>By understanding the challenges and needs of users from different walks of life, developers can create interfaces that are intuitive, inclusive, and cater to a wide range of users.</p>
<h2 id="heading-importance-of-empathy-in-software-development">Importance of Empathy in Software Development 🧑💻👩💻</h2>
<p>Empathy is a key element in designing user-centric software. Developers should strive to put themselves in the shoes of the end user, considering their unique circumstances, limitations, and preferences.</p>
<p>By empathizing with users who may have limited technical knowledge or unconventional work experiences, developers can create software that is easy to understand and use.</p>
<h2 id="heading-tracking-usage-behavior-through-user-research">Tracking Usage Behavior Through User Research 🏃♂️</h2>
<p>User research plays a vital role in understanding how people interact with software. By conducting <strong>interviews</strong>, <strong>surveys</strong>, and <strong>usability tests</strong>, developers can gain insights into the behaviours and preferences of their target users.</p>
<p>When designing software for users with varying levels of education or professional backgrounds, it is important to conduct research specifically tailored to those groups.</p>
<p>This research can help uncover pain points, identify usability issues, and inform design decisions that improve the overall user experience.</p>
<h2 id="heading-designing-for-accessibility">Designing for Accessibility 🦾</h2>
<p>Inclusive software development also entails designing for accessibility. Developers should consider the needs of users with disabilities or limited digital literacy.</p>
<p>Incorporating features such as <strong>clear and concise instructions,</strong> <strong>visual cues</strong>, and <strong>easily navigable interfaces</strong> can make the software more accessible to a wider audience.</p>
<p>By embracing accessibility standards and guidelines, developers can ensure that their software is usable by everyone, regardless of their educational background or profession.</p>
<h2 id="heading-conclusion">Conclusion 🥇🙏</h2>
<p>As software developers, we have the power to shape the experiences of millions of users worldwide. It is our responsibility to design software that is inclusive and accessible to users from diverse backgrounds, including those who may be less educated or work in unconventional professions.</p>
<p>By approaching development with <strong>empathy</strong>, <strong>conducting user research</strong>, and paying attention to <strong>accessibility</strong>, we can create software that truly caters to the needs of all users.</p>
<p>Let us strive to build a digital world that embraces diversity and empowers every user to leverage the benefits of technology.</p>
<p>Cheers! 🥂🥂</p>
]]></content:encoded></item><item><title><![CDATA[A Study on End-to-End Testing Framework Cypress in comparison to Selenium]]></title><description><![CDATA[What is Cypress?
Cypress is a new-age end-to-end testing tool. End-to-end testing ensures the application is tested exactly how the users are going to interact. Its installation is effortless, usage is smooth, and it runs very fast.
Let’s discuss mor...]]></description><link>https://blog.taditdash.com/a-study-on-end-to-end-testing-framework-cypress-in-comparison-to-selenium</link><guid isPermaLink="true">https://blog.taditdash.com/a-study-on-end-to-end-testing-framework-cypress-in-comparison-to-selenium</guid><category><![CDATA[Cypress]]></category><category><![CDATA[selenium]]></category><category><![CDATA[automation]]></category><category><![CDATA[automation testing ]]></category><category><![CDATA[JavaScript]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Sat, 04 Feb 2023 04:45:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1675484367318/a09c7580-d55d-43b3-803d-107bf517cf49.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-what-is-cypress">What is Cypress?</h1>
<p>Cypress is a new-age end-to-end testing tool. End-to-end testing ensures the application is tested exactly how the users are going to interact. Its installation is effortless, usage is smooth, and it runs very fast.</p>
<p>Let’s discuss more in the following sections.</p>
<h1 id="heading-why-are-we-even-thinking-of-cypress">Why are we even thinking of Cypress?</h1>
<p>For a long time, testing has been an integral part of the software Quality Assurance department. However, the tools supporting this culture were merely doing 100% justification to the capabilities of modern development teams. With the agile way of software development, it is essential now that team members get all tools that can support quick and reliable feedback on the codes.</p>
<p>What if I tell you, that developers would now be able to write automated tests with their existing web technology knowledge using almost zero configuration?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675484959764/eff13932-9158-47b2-818d-e15874d2d683.gif" alt class="image--center mx-auto" /></p>
<p>Isn’t that interesting? 😮 Indeed.</p>
<p>“Developers writing automated tests” – this seems unreal, but now it is possible. That is where Cypress comes into the picture. It is a revolution that empowers the whole development team and not only the QA engineers.</p>
<p>Let’s quickly explore the features to find out how painless and swift it can be.</p>
<h1 id="heading-you-will-care-about-the-below-points-as-a-development-team">You will care about the below points as a development team</h1>
<p>In this section, we will quickly discuss the unique features that Cypress is offering.</p>
<h2 id="heading-the-tool-is-amazing">The Tool is amazing</h2>
<p>Let me give you a quick walkthrough of the tool. Imagine you have written some Cypress test cases in a spec file and run the Cypress runner using the following <code>npx</code> command.</p>
<p><code>npx cypress run</code></p>
<p>It will blow up your mind. The UI is so soothing and provides all information needed to start up.</p>
<p>See the screenshot below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675430732466/8a992431-20a7-4e85-8343-e9c0964edaa0.png" alt class="image--center mx-auto" /></p>
<p>It provides you with two options either <em>E2E Testing</em> or <em>Component Testing</em>. Even all docs are provided inside the tool, no need to go to google and ask. Refer to the screenshot of the docs section below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675430765546/5083573a-ab1b-4237-b8a3-d352694d41dc.png" alt class="image--center mx-auto" /></p>
<p>Now, after you select a type, it asks you for a browser. Super user experience, I must say. Here is the capture.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675430799599/a121091f-8cfe-4fec-b0ae-282f643346e3.png" alt class="image--center mx-auto" /></p>
<p>It is time to see the main screen in action that lists all the test files. See the screenshot below. In this case, it is displaying one test file named <a target="_blank" href="http://todo.cy"><em>todo.cy</em></a><em>.js</em>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436541191/24fe8342-8216-4690-a020-227870feb93d.png" alt class="image--center mx-auto" /></p>
<p>When you click on the test file name, it will try to run all cases written inside the spec file. Let's have a look.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436593803/b04ddbca-68d2-4426-bf75-94df0187e1f7.png" alt class="image--center mx-auto" /></p>
<p>Oops! We got one error. Notice how a detailed message is given. This error is because I forgot to run my app. So, I will run the app, and then we will explore other features in the following sections.</p>
<h2 id="heading-an-update-is-instant-no-need-to-rerun-cypress">An update is instant, no need to rerun Cypress</h2>
<p>Once you make any change to the spec file, Cypress detects and reruns the tests for you. Wonderful. 😊</p>
<h2 id="heading-direct-instant-feedback-on-what-cypress-is-doing-with-your-cases">Direct instant feedback on what Cypress is doing with your cases</h2>
<p>Every command like <a target="_blank" href="http://cy.click"><code>cy.click</code></a><code>()</code> (to trigger the click event of an HTML element), <code>cy.type()</code> (to enter some data inside the HTML element) when run by the runner, logs all details about it. It means a lot to the team for debugging. You can go through each step on the left panel and see visually on the right panel how it interacts with the UI with the command.</p>
<p>Refer to the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436681430/1945ccb0-9650-42a4-9329-a596055f8053.png" alt class="image--center mx-auto" /></p>
<p>The left panel has logged all the steps with details. As soon as you hover over any step, you will see the element getting highlighted on the UI on the right side.</p>
<h2 id="heading-interactive-time-traveling">Interactive time-traveling</h2>
<p>Imagine that you are going to each command and step to determine what happened on the UI. That is what we always wish to do as developers, right? The interactive time travel feature gives you the flexibility to go back to each step to see what happened at that time of execution. ⏳</p>
<h2 id="heading-debugging-is-not-a-pain-anymore">Debugging is not a pain anymore</h2>
<p>Any error in the test cases will be properly presented with details about the error along with the line number. See the screenshot below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436741326/4ae03e65-7536-46d6-8953-7975d972c4ea.png" alt class="image--center mx-auto" /></p>
<p>Surprisingly, it also has a stack trace that can take you to the line number inside the spec file directly. Try that. It is seamless. You will land up on your IDE with the file opened and the cursor at the error line number. 🧑‍💻</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436776033/533c9d5c-8ebe-4919-9025-794efeeb6fd9.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-zero-server-involvement">Zero server involvement</h2>
<p>With the features like spies, stubs, and clocks, there is no requirement for an actual server. With interceptors, the API calls can be manipulated with a custom response by designing mocks. This is very powerful and promotes TDD. Test case development can be started without a backend.</p>
<h2 id="heading-screenshots-and-videos"><strong>Screenshots and Videos</strong></h2>
<p>Cypress can take screenshots and videos of the test case. It is especially useful when test cases fail.</p>
<h2 id="heading-cypress-supports-any-front-end-framework-or-website">Cypress supports any front-end framework or website</h2>
<p>As long as the application or website runs inside a browser, Cypress can test your cases beautifully. All modern JavaScript frameworks like <em>Vue</em>, <em>React</em>, <em>Angular</em>, <em>Elm</em>, etc. are supported. It can even render any server-rendered apps.</p>
<h2 id="heading-real-world-examples">Real-world Examples</h2>
<p>The team has crafted a dedicated website just for learning Cypress and its features with real-world examples. Another reason to cherish. Here is the Link - <a target="_blank" href="https://learn.cypress.io/real-world-examples">https://learn.cypress.io/real-world-examples</a>.</p>
<p>Now, let's see how Cypress stands in comparison to Selenium.</p>
<h1 id="heading-cypress-vs-selenium">Cypress Vs Selenium</h1>
<p>In this section, we will compare some key features between Cypress and Selenium.</p>
<h2 id="heading-getting-started">Getting Started</h2>
<p>This is something I care about while evaluating software.</p>
<p><strong><em>With Cypress,</em></strong></p>
<p>Inside the project directory, just run the following command</p>
<p><code>npm install cypress --save-dev</code></p>
<p>(NOTE: Assuming Node.js and npm installed)</p>
<p>or download from <a target="_blank" href="https://download.cypress.io/desktop">https://download.cypress.io/desktop</a>. That is it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436827753/5611cd51-2e2f-4111-8870-879a82718acd.png" alt class="image--center mx-auto" /></p>
<p><strong><em>However, with Selenium,</em></strong></p>
<p>It is not that easy to start. There is no clear path to getting started. See the screenshot below of the getting started page. There is quite a read and also some concepts you need to grasp.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436900338/afe1ab83-8b4c-4adc-a22c-a46d62255436.png" alt class="image--center mx-auto" /></p>
<p>Now little below on the same page, on scrolling down, you will see multiple links. Refer to the following screenshot. It makes life more complicated.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675436917191/9164a900-17f6-4b50-8eb6-89f6668e160d.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-language-support">Language Support</h2>
<p><strong><em>With Cypress,</em></strong></p>
<p>It is just JavaScript. Cypress supports writing test cases in JavaScript. All web developers know JavaScript or might have used it at some point in their projects/careers.</p>
<p>The learning curve for Cypress is shallow, trust me. Personally, I know QA teams have started Cypress in just two days without any external or trainer help.</p>
<p><strong><em>However, with Selenium,</em></strong></p>
<p>It supports <em>JavaScript (Node.js), C#, Groovy, Java, Perl, PHP, Python, C#</em>, etc. This can be treated as an advantage because team members with different skills can contribute.</p>
<h2 id="heading-end-to-end-tests">End-to-End Tests</h2>
<p><strong><em>With Cypress,</em></strong></p>
<p>The goal is to write and execute end-to-end test cases and not unit test cases for the back-end services. That means testing how the user is going to experience the product.</p>
<p>Writing such tests with Cypress is very engaging. The syntax to fetch HTML elements from the web page is straightforward with selectors similar to JavaScript.</p>
<p><strong><em>However, with Selenium,</em></strong></p>
<p>End-to-end tests are problematic in Selenium. They tend to encourage the usage of <em>XPath</em> which can go wrong for complex HTML structures. Now, imagine the team debugging why certain tests fail. It can be a nightmare to go through these <em>XPaths</em> and find out the issues. Maintenance becomes very difficult.</p>
<h2 id="heading-debugging">Debugging</h2>
<p>Undoubtedly, Cypress is the winner in this case.</p>
<p><strong><em>With Cypress,</em></strong></p>
<p>The tests directly run inside the browser. The execution process of each step inside each test case is crystal clear. Cypress grabs snapshots at the moment of test execution. This allows the development team to hover over a specific test to see exactly what happened at each step. The error messages are super concise and to the point.</p>
<p>The browser developer tool can also be leveraged to find out details about the tests. Check out the following video.</p>
<p><a target="_blank" href="https://vimeo.com/242961930#t=264s">Cypress Vimeo</a></p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://vimeo.com/242961930#t=264s">https://vimeo.com/242961930#t=264s</a></div>
<p> </p>
<p><strong><em>However, with Selenium,</em></strong></p>
<p>Again, this is not straightforward and out of the box. Debugging an <em>XPath</em> error can be challenging and time-consuming.</p>
<h2 id="heading-cypress-is-fast">Cypress is fast</h2>
<p><strong><em>With Cypress,</em></strong></p>
<p>As testing is always an integral part of the development process, it becomes fast because of real-time execution. It is designed to support the simultaneous execution of tests and codes, thanks to the new architecture built from the ground up.</p>
<p><strong><em>However, with Selenium,</em></strong></p>
<p>It runs as a different component not integrated with the code base. Tough to visualize your test then and there when you develop it. Thus, it is slow and does not contribute to fast-paced environments.</p>
<h1 id="heading-known-limitations">Known Limitations</h1>
<p>With so many jaw-dropping features, it still, Cypress fails in certain scenarios. ☹ Let's find out.</p>
<ol>
<li><p>Testing for mobile screens is carried out inside a browser, so native device functionality like the camera or fingerprint authentication testing is not possible at this moment.</p>
</li>
<li><p>Different tabs or window testing are not possible.</p>
</li>
<li><p>Iframe testing is not possible at this moment, but there is an experiment going on.</p>
</li>
<li><p>Currently, Cypress supports testing on Chrome, Edge, and Firefox browsers.</p>
</li>
</ol>
<h1 id="heading-future-improvements">Future Improvements</h1>
<p>The roadmap can be explored from the <a target="_blank" href="https://github.com/orgs/cypress-io/projects/13/views/1">Cypress Priority board</a>.  One of the features planned is the support for the browsers Safari and Internet Explorer.</p>
<h1 id="heading-use-cases-of-companies-using-cypress">Use Cases of Companies using Cypress</h1>
<p>We looked at a lot of features that the development team enjoys while working on Cypress. That is a great reason to adopt this framework.</p>
<p>Moreover, let’s analyze some real use cases with companies that adopted Cypress to improve their development processes.</p>
<h2 id="heading-the-godaddy-development-team-wanted-to-deploy-fast-and-increase-test-coverage">The GoDaddy development team wanted to deploy fast and increase test coverage</h2>
<p><img src="https://mma.prnewswire.com/media/819539/GoDaddy_Logo.jpg?p=twitter" alt="GoDaddy Reports Fourth Quarter and Full Year 2021 Results" /></p>
<p>In this <a target="_blank" href="https://youtu.be/ZSbNT-Fff9A">recorded session</a> by the <em>GoDaddy</em> team, they touched upon a lot of pain points of testing with <em>Selenium</em>. Here is a capture of the video.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675440042578/f26844f5-1666-4cd8-a06b-8d50a49f6513.png" alt class="image--center mx-auto" /></p>
<p>See how they were struggling with the slow development process due to limitations, flakiness, and very low test coverages.</p>
<p>As a result, they started to evaluate a lot of tools like <a target="_blank" href="http://webdriver.io"><em>webdriver.io</em></a><em>, Nightwatch, Appium</em>, etc. Finally settled down with Cypress due to the following reasons.</p>
<ul>
<li><p>Community &amp; Docs – The community is mature and Docs have everything well maintained</p>
</li>
<li><p>Smoke Test</p>
</li>
<li><p>Dashboard – That displays all the details about the tests</p>
</li>
<li><p>Live execution – This is amazing as you can see the tests running inside the browser.</p>
</li>
</ul>
<p>See the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675440261506/93863d24-cc04-47d8-8ab2-55ead09bb7f6.png" alt class="image--center mx-auto" /></p>
<p>When they surveyed the developers after adoption, it was inspiring. Refer to the image below for some feedback.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675440300209/60479c5c-283e-4252-b451-673dca939d86.png" alt class="image--center mx-auto" /></p>
<p>The results that the GoDaddy team started to see are mentioned below.</p>
<ul>
<li><p>70% increase in productivity</p>
</li>
<li><p>75% decrease in test maintenance</p>
</li>
<li><p>2,500 tests run daily</p>
</li>
<li><p>100% new feature test coverage</p>
</li>
</ul>
<h2 id="heading-monterail-switched-to-cypress-from-nightwatchjs-which-is-a-selenium-based-testing-tool">Monterail switched to Cypress from Nightwatch.js which is a selenium-based testing tool</h2>
<p><img src="https://www.monterail.com/hubfs/Monterail%20logo/svg/Monterail%20Logo%20Classic.svg" alt="We develop and design Web &amp; mobile apps · Monterail" /></p>
<p>While they achieved 30% coverage with <em>Nightwatch.js</em>, when asked about the stability and security of the application by the client, they faced challenges to improve the coverage. That is because of the following three reasons.</p>
<ol>
<li><p>Selenium Web Driver is issue-prone – It can throw issues without giving friendly error messages.</p>
</li>
<li><p>Test stability – Test cases can fail on any random attempt.</p>
</li>
<li><p>Dissatisfied with the pace of writing new tests – Writing test cases, running, and observation can take an ample amount of time.</p>
</li>
</ol>
<p>The detailed case study is documented in this <a target="_blank" href="https://www.monterail.com/blog/end-to-end-testing-with-cypress">blog post</a>.</p>
<h2 id="heading-quizlet-not-only-switched-to-cypress-for-language-reasons-but-also-due-to-some-critical-issues-with-capybara-again-a-selenium-based-testing-tool">Quizlet not only switched to Cypress for language reasons but also due to some critical issues with Capybara – again a selenium-based testing tool</h2>
<p><img src="https://www.generalatlantic.com/wp-content/uploads/2020/05/quizlet-logo-indigo-rgb.jpg" alt="Quizlet Raises Series C Funding from General Atlantic | General Atlantic" /></p>
<p>Documented in <a target="_blank" href="https://medium.com/tech-quizlet/cypress-the-future-of-end-to-end-testing-for-web-applications-8ee108c5b255">this medium blog</a>, the explanation is to the point on why they moved from <em>Capybara</em> but did not select <em>Cypress</em> straight away. They evaluated all options and their study circles around the following points.</p>
<ol>
<li><p>Language – They wanted to write tests in a language matching what skill set they had.</p>
</li>
<li><p>Flaky tests – <em>Capybara</em> tests were failing with errors.</p>
</li>
<li><p>Slowness with the runner – Selenium-based testing tools are very slow because they spin up a browser for every test.</p>
</li>
</ol>
<p>They spent a good amount of time researching the tools like <em>Puppeteer</em> and <em>TestCafe</em>. These tools came as somewhat useful but again they fail to convince the management of documentation, cross-browser support, debugging, community support, etc.</p>
<p>Refer to the picture of the chart taken from the blog above.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675441207252/f7e28482-213d-4bdd-9400-91dd52c174db.png" alt class="image--center mx-auto" /></p>
<p>Eventually, <em>Cypress</em> is the winner. 🥇</p>
<h2 id="heading-pixelcabin-wanted-to-feel-confident-every-time-they-deploy">Pixelcabin wanted to feel confident every time they deploy</h2>
<p><img src="https://uploads-ssl.webflow.com/61f54f867e39ff1ef2da097d/62322884637029725ff5f5ed_Pixelcabin-BLK-Logo%E2%80%93LogoType.png" alt="Pixelcabin - Shopify Plus Agency" /></p>
<p>The goals of <em>Pixelcabin</em> were to achieve the following points. The picture is taken from the video of the session by Michael Shannon, (Co-Founder). The <a target="_blank" href="https://www.youtube.com/watch?v=kRTma2CztxE">video</a> is embedded below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1675441222846/39d39bd4-8250-433c-92ab-22970b74f9f0.png" alt class="image--center mx-auto" /></p>
<p>In the video embedded below, Michael mentions the motivation behind choosing <em>Cypress</em> as the automation tool and <em>TravisCI</em> to run the tests in the Continuous Integration environment.</p>
<p>The team was taken aback by the test suite recording with screenshots and videos.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=kRTma2CztxE">https://www.youtube.com/watch?v=kRTma2CztxE</a></div>
<p> </p>
<p>More case studies can be found at - <a target="_blank" href="https://www.cypress.io/case-studies/">https://www.cypress.io/case-studies/</a></p>
<h1 id="heading-should-i-start-in-my-companyproject">Should I start in my company/project?</h1>
<p>We have seen a lot of proof that Cypress is a magic wand for the development teams. Now here are some suggestions for the software development teams to consider its adoption.</p>
<h2 id="heading-getting-started-is-easy">Getting started is easy</h2>
<p>It is not going to hurt the existing team to start up. You can argue that Cypress can be complicated for testers who are into manual testing. However, it is not really. Cypress documentation even makes it more interactive. Some context of JavaScript, and they are good to go. For developers who are into front-end development, it is just the cream on top of the cake. 🏃‍♂️</p>
<h2 id="heading-support-with-widely-used-language-javascript">Support with widely used language JavaScript</h2>
<p>Selenium can be handy in terms of a wide range of technology to write test cases. Still, the problem Cypress is solving is to bring the whole development team together with one universal language. Developers can see their code running inside the browser itself with details about the tests. At the same time, QAs can enjoy working without extra effort on external libraries or drivers.</p>
<h2 id="heading-end-to-end-tests-that-give-you-confidence-in-user-experience">End-to-end Tests that give you confidence in User Experience</h2>
<p>Think of the front-end development team in your organization who are always looking for UX feedback from product owners or real users. They can now able to get the feedback right there while developing the feature way before it goes to the stakeholders.</p>
<p>Therefore, with minimum configuration, if both Developers and QA engineers can collaborate with simple syntax to imitate user behavior, why not adopt that? 🥂</p>
<h2 id="heading-debugging-is-effortless">Debugging is effortless</h2>
<p>We have discussed above how debugging is hassle-free in Cypress. 🤝 For fast development, better debugging gives an edge. Moreover, maintenance becomes hassle free when breaking changes are introduced.</p>
<h2 id="heading-superfast-live-test-runner">Superfast Live Test Runner</h2>
<p>For a development team, it is always a dream to ship bug-free code, and when it comes to the execution of tests while coding, it contributes a lot to self-satisfaction. 😊</p>
<p>On the other hand, give this tool to an existing QA team with prior automation experience with different frameworks. They will feel more connected to the code base along with the performance.</p>
<h2 id="heading-integrations-with-continuous-integration-tools">Integrations with Continuous Integration Tools</h2>
<p>This is a need of this hour and Cypress has it. Comfortable integration with CI like <em>GitLab CI</em>, <em>Azure DevOps</em>, <em>TravisCI</em>, etc provides confidence to deploy fast and iterate.</p>
<h1 id="heading-adoption-strategies">Adoption Strategies</h1>
<p>To adopt Cypress’s End-to-end Automation framework within the development team, some questions need to be answered first. 🤔Here are they.</p>
<ol>
<li><p>Do you have a Web UI that is used by users on browsers <em>Chrome</em>, <em>Edge</em> and <em>Firefox</em>, and <em>Safari</em>, <em>IE</em> can be excluded?</p>
</li>
<li><p>Do you have iframes implemented inside the web pages and do you need to test them?</p>
</li>
<li><p>Do you have mobile apps that need to be tested?</p>
</li>
</ol>
<p>If your answer is no to the above questions, you can go with Cypress. If you have both web and mobile apps, then better to test the web app with Cypress and select some other framework for the mobile app testing.</p>
<p>Now, to start up, we should do a POC to find out all features. We can take help from the real-world examples website from Cypress. Otherwise, some new and less critical projects can experiment with Cypress to observe its suitability. Then, other project teams can adopt it.</p>
<h1 id="heading-final-thoughts">Final Thoughts</h1>
<p>Cypress came as a revolution with an unconventional way to deal with end-to-end automation testing. It is a game-changer for the development teams in terms of delivering quality software in a defined time and it does not add much complexity on top of the development process.</p>
<p>A go-ahead. 🤝👍⏩</p>
<h1 id="heading-feedback">Feedback</h1>
<p>Let me know if you liked what you read. Please share with your friends and colleagues. 🙏🙏</p>
<h1 id="heading-references">References</h1>
<ul>
<li><p><a target="_blank" href="https://cypress.io/">https://cypress.io/</a></p>
</li>
<li><p><a target="_blank" href="https://learn.cypress.io/real-world-examples">https://learn.cypress.io/real-world-examples</a></p>
</li>
<li><p><a target="_blank" href="https://www.cypress.io/blog/2020/07/08/end-to-end-testing-mobile-apps-with-ionic-and-cypress/">https://www.cypress.io/blog/2020/07/08/end-to-end-testing-mobile-apps-with-ionic-and-cypress/</a></p>
</li>
<li><p><a target="_blank" href="https://www.cypress.io/case-studies/">https://www.cypress.io/case-studies/</a></p>
</li>
<li><p><a target="_blank" href="https://medium.com/tech-quizlet/cypress-the-future-of-end-to-end-testing-for-web-applications-8ee108c5b255">https://medium.com/tech-quizlet/cypress-the-future-of-end-to-end-testing-for-web-applications-8ee108c5b255</a></p>
</li>
<li><p><a target="_blank" href="https://www.monterail.com/blog/end-to-end-testing-with-cypress">https://www.monterail.com/blog/end-to-end-testing-with-cypress</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[GIT Master Branch History Lost! - A Quick Solution]]></title><description><![CDATA[Background
While working on a past project, we encountered a problem while pushing the local changes from a new computer that has an old version of the master branch. We did not realize it was old initially though. 😋
Issue while merging
The error wa...]]></description><link>https://blog.taditdash.com/git-master-branch-history-lost-a-quick-solution</link><guid isPermaLink="true">https://blog.taditdash.com/git-master-branch-history-lost-a-quick-solution</guid><category><![CDATA[Git]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[GitLab]]></category><category><![CDATA[repository]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Sun, 20 Nov 2022 15:02:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1668956271523/DABOTrMZF.gif" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-background">Background</h1>
<p>While working on a past project, we encountered a problem while pushing the local changes from a new computer that has an old version of the <code>master</code> branch. We did not realize it was old initially though. 😋</p>
<h1 id="heading-issue-while-merging">Issue while merging</h1>
<p>The error was not so clear and it was just saying push failed. Thinking that it might be an access issue, we then tried to give that user the required access by changing the role to maintainer at GitLab repository members settings. Nothing helped. 😭
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668951921212/LYu7Hn7Hd.gif" alt="HotMessGIF.gif" /></p>
<p>Then we messed up the master branch by forcing a push from that computer. 😭😭</p>
<pre><code>git push --force
</code></pre><p>As a result, the master branch got replaced with the old version, and all its history got removed. 😰</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668951993794/RDnJp9h-N.gif" alt="OmgOmgOmgOmgGIF.gif" /></p>
<h1 id="heading-what-to-do-now">What to do now?</h1>
<p>The team was in shock. No one has a clue. After a round of research, we came to a conclusion. To restore everything to normal, we then followed the steps mentioned below. The idea is to make the <code>master</code> point to an old commit that can be considered as most recent. Which means we need to find it somewhere. 🔬</p>
<h2 id="heading-find-out-a-recent-master-commit">Find out a recent <code>master</code> commit</h2>
<p>From another computer of a teammate, that had the latest <code>master</code> branch, we pointed the head to a previous commit.</p>
<pre><code>git reset &lt;commit hash&gt;
</code></pre><p><strong>NOTE:</strong> Commit hash can be fetched by looking into the <code>git log</code>.</p>
<h2 id="heading-force-push-to-remote-master">Force push to remote <code>master</code></h2>
<p>Then pushed that local master to the remote master by force again.</p>
<pre><code>git push --force
</code></pre><p>Now, the remote <code>master</code> pointed to a commit that was not so old and solved the purpose. 
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1668955481162/XqY6fYpJF.gif" alt="AomSusharAomGIF.gif" /></p>
<h1 id="heading-learning">Learning</h1>
<p>Due to all this, we learned a process that we need to follow every time we merge something to the remote <code>master</code>. 🎉</p>
<p>Let’s analyze that below.
 </p>
<h2 id="heading-basic-process-of-new-branch-commit-push-and-merge">Basic Process of New Branch Commit, Push, and Merge</h2>
<p>Here are some basic steps we followed in the team to prevent this issue in the future. Whenever you are ready with a change that can be merged to <code>master</code>, follow these steps.</p>
<ol>
<li>Update the local <code>master</code> branch.<pre><code>git pull origin master
</code></pre></li>
<li>Create a new local branch from the local <code>master</code>.<pre><code>git branch SomeInterestingName
</code></pre></li>
<li>Do your changes in the new branch as needed for the task.</li>
<li>Your changes are ready.</li>
<li>Commit and push.<pre><code>git commit -m <span class="hljs-string">"Some message"</span>
git push origin SomeInterestingBranchName
</code></pre></li>
<li><p>Merge <code>master</code> and create a PR.</p>
<p>a. Now checkout <code>master</code>.</p>
<pre><code>git checkout master
</code></pre><p>b. Update <code>master</code>.</p>
<pre><code>git pull origin master
</code></pre><p>c. Now checkout your new branch.</p>
<pre><code>git checkout SomeInterestingBranchName
</code></pre><p>d. Let’s merge <code>master</code> into your new branch.</p>
<pre><code>git merge master
</code></pre><p>e. Commit and push.</p>
<pre><code>git commit -m <span class="hljs-string">"Some message"</span>
git push origin SomeInterestingBranchName
</code></pre><p>f. Your branch and master are now in sync.</p>
<p>g. Now go to your SCM like GitLab/GitHub and select your branch.</p>
<p>h. Create a Pull Request with the target branch as <code>master</code>.</p>
<p>i. After PR is approved, merge after resolving the conflicts, if any.
 </p>
</li>
</ol>
<h1 id="heading-would-like-to-hear-from-you">Would like to hear from you?</h1>
<p>Have you faced such a situation? How did you solve it? It would be very interesting to discuss. Put a comment below. 🙏</p>
<p>Thanks for reading. Have a nice day. 🙂</p>
]]></content:encoded></item><item><title><![CDATA[Effortless Swagger UI Installation]]></title><description><![CDATA[Background 💭
I am working on a blog on the concepts of Open API Specification, where I came across Swagger UI and Swagger Editor. I needed these two tools on my machine so that I could make my hands dirty trying our APIs. Let's see how we can instal...]]></description><link>https://blog.taditdash.com/effortless-swagger-ui-installation</link><guid isPermaLink="true">https://blog.taditdash.com/effortless-swagger-ui-installation</guid><category><![CDATA[swagger-ui]]></category><category><![CDATA[swagger]]></category><category><![CDATA[APIs]]></category><category><![CDATA[documentation]]></category><category><![CDATA[GitHub]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Sat, 05 Nov 2022 08:35:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1667637199103/0j9DGuDR7.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-background">Background 💭</h1>
<p>I am working on a blog on the concepts of <em>Open API Specification</em>, where I came across <em>Swagger UI</em> and <em>Swagger Editor</em>. I needed these two tools on my machine so that I could make my hands dirty trying our APIs. Let's see how we can install <em>Swagger UI</em> in an effortless manner.</p>
<h1 id="heading-what-is-swagger-ui">What is Swagger UI? 🤔</h1>
<p>APIs are magic. When invoked, they just perform specific tasks that the invoker has said them to. It is not easy to explain this to anyone in an organization unless we provide them with an interface to actually see and try them out. </p>
<p>That is where <em>Swagger UI</em> comes into the picture. It is an open-source tool. When you configure Swagger with your API, it can beautifully present everything about it like what methods it follows, what URLs are supported, and what data it expects, everything.</p>
<p>See the screenshot of the demo <em>pet store API</em> UI by Swagger.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667578000272/cpkm2z3P9.png" alt="Swagger UI Pet Store Demo" />
Notice the URL - <a target="_blank" href="https://petstore.swagger.io/">https://petstore.swagger.io/</a>. It is running on the Swagger domain. As we know, it is open-source, so why can't we run it locally and see if it working?</p>
<p>Let's get started.</p>
<h1 id="heading-quick-installation">Quick Installation 👇</h1>
<p>Here are the steps that we can follow.</p>
<ol>
<li>First of all, we need to go to the <a target="_blank" href="https://github.com/swagger-api/swagger-ui">Swagger UI Github Page</a>.</li>
<li>Now move to the <em>Releases</em> on the right side section and click on the Latest Release number. At the time of writing this blog, it is saying <a target="_blank" href="https://github.com/swagger-api/swagger-ui/releases/tag/v4.15.2">Swagger UI v4.15.2 Released!</a>.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667578593831/qj5kYiWMY.png" alt="Swagger UI Releases Section" /></li>
<li>You will land on the particular release page with the <em>Assets</em> containing the source code. See the below screenshot.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667578950662/S6zRfWkAQ.png" alt="Swagger UI v4.15.2 Release Page" /></li>
<li>We are interested in the <code>zip</code> file. Let's download that and then extract it. Here it is how it will look on your system.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667579273085/Y4aNKq_EA.png" alt="Swagger UI Zip and Extract.png" /></li>
<li>Now that we got the whole source code, let's dig inside. You will see a <code>dist</code> folder and an <code>index.html</code> file inside that.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667579447058/jBgZ0sMR7.png" alt="image.png" /></li>
<li>If you open this file on a browser, it will display the pet store API details as we saw earlier online. Here is the screenshot.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667579592782/r9wZIfpVX.png" alt="Swagger UI Pet Store running on Local" /></li>
<li>If you want to run a server and host locally, then open a command prompt and move to the folder where you have the Swagger UI extracted. The prerequisite will be to install <a target="_blank" href="https://www.npmjs.com/package/http-server"><code>http-server</code> npm package</a>. Then it is just a matter of running the following command.<pre><code>http-server swagger-ui
</code></pre><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667635944662/2Myepv_sZ.png" alt="http-server running Swagger UI" /></li>
<li>Now when you open the URL mentioned in the command prompt and append <code>dist</code> to it, it will open the same UI that we saw earlier.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667636671613/jbRIJrhP-.png" alt="Swagger UI Running on http-server.png" /></li>
</ol>
<h1 id="heading-next-steps">Next Steps 🪜</h1>
<p>Going forward, we will install <em>Swagger Editor</em> to edit an API and see the changes running on the <em>Swagger UI</em>. Interesting time ahead! Stay tuned. </p>
<h1 id="heading-feedback">Feedback 🙌</h1>
<p>If you liked my blog, don't forget to like and share. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1667636772879/l9xuQ8twC.gif" alt="MilkaMilkaTenderWordsGIF.gif" /></p>
]]></content:encoded></item><item><title><![CDATA[Add Inline JavaScript and use Variables in Pug]]></title><description><![CDATA[Background
Recently, I started revamping my personal website and used an opensource template from Github - startbootstrap-freelancer. When I started, I saw an index.pug file inside the project that is driving the whole HTML. It was new and interestin...]]></description><link>https://blog.taditdash.com/add-inline-javascript-and-use-variables-in-pug</link><guid isPermaLink="true">https://blog.taditdash.com/add-inline-javascript-and-use-variables-in-pug</guid><category><![CDATA[Pug]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[HTML]]></category><category><![CDATA[portfolio]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Fri, 21 Oct 2022 17:03:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1666346663064/vQZSzjZq8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-background">Background</h1>
<p>Recently, I started revamping my personal website and used an opensource template from Github - <a target="_blank" href="https://github.com/StartBootstrap/startbootstrap-freelancer">startbootstrap-freelancer</a>. When I started, I saw an <code>index.pug</code> file inside the project that is driving the whole HTML. It was new and interesting. I was able to fairly understand and make changes. Let's discuss one of the problems that I faced with it and how I solved it.</p>
<h1 id="heading-problem">Problem</h1>
<p>In my blog, there is a footer where I am showing the current year. Here it is.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666347315021/EwG3iEYDm.png" alt="image.png" /></p>
<p>However, it was static and I wanted to make it dynamic. Meaning, going forward, no need to modify the HTML again and again. The first thing came to my mind is.</p>
<pre><code><span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getFullYear();
</code></pre><p>Now, the thing is, we just need to take this code and place it at the correct place inside the HTML file templated by the <code>index.pug</code>. </p>
<h1 id="heading-investigation">Investigation</h1>
<p>When I checked the code inside the <code>index.pug</code>, I saw this.</p>
<pre><code><span class="hljs-comment">// Copyright Section</span>
div.copyright.py<span class="hljs-number">-4.</span>text-center.text-white
    .container
        small Copyright &amp;copy; 
        a(href=<span class="hljs-string">'http://taditdash.com'</span>)
            | Tadit Dash
        | <span class="hljs-number">2021</span>
</code></pre><p>Basically, this pug code will generate a division with mentioned classes and then another container division inside it. At last, the two children would be a small Copyright text and an anchor.</p>
<p>Here is the rendered HTML screenshot from the Chrome developer tool.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1666356242422/FBLf6J0Tg.png" alt="image.png" /></p>
<p>Now the challenge is to remove the static 2021 and replace it with the dynamic year from the JavaScript Date Object.</p>
<h1 id="heading-solution">Solution</h1>
<p>Upon searching on the internet I got some answers those talked about including inline JavaScript inside the pug file, however, they did not really talk about how to take one JavaScript variable and display it in the pug.</p>
<p>Let's understand how to include an inline JavaScript block inside the pug file. Very easy! Have a look.</p>
<pre><code>script.
    var currentYear = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getFullYear();
</code></pre><p>Notice the dot (.) after <code>script</code>. This is important. If not present, then it will think of <code>script</code> as an HTML element.</p>
<p>Alright. We get the current dynamic year. Now, we need to display it inside the footer where it is intended. Unfortunately, I could not able to find any straightforward way to directly use this <code>currentYear</code> variable with any HTML element.</p>
<p>Thus, I tried a different approach. With JavaScript, it will be easy to find an element and push the content inside it. Let's see the updated code.</p>
<pre><code>script.
    document.getElementById(<span class="hljs-string">'year'</span>).textContent = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getFullYear();
</code></pre><p>Okay, so just need to declare an element with id <code>year</code>. I have added a <code>span</code>. Let's add that.</p>
<pre><code><span class="hljs-comment">// Copyright Section</span>
div.copyright.py<span class="hljs-number">-4.</span>text-center.text-white
    .container
        small Copyright &amp;copy; 
        a(href=<span class="hljs-string">'http://taditdash.com'</span>)
            | Tadit Dash
        | 
        span#year
</code></pre><p>So, the static year is replaced with a <code>span</code> with id <code>year</code>. A small thing though. The span is declared on the next line after the bar (|). Otherwise, it will just be regarded as plain text and not an HTML element. </p>
<p>This magically worked. In case you want to check out my version of the repo, visit - <a target="_blank" href="https://github.com/taditdash/startbootstrap-freelancer/">taditdash/startbootstrap-freelancer</a></p>
<h1 id="heading-feedback">Feedback</h1>
<p>Your feedback is very important to me. Don't hesitate to comment.</p>
<p>Thanks for reading. Have a nice day! 😍🙌💾</p>
]]></content:encoded></item><item><title><![CDATA[Getting started on Microservices with .NET 💓]]></title><description><![CDATA[In this blog, we will go through my first experience in trying out Microservices with .NET 5. Though it looks very easy from the official documentation, however, I am documenting my experience as I was following through. I will explain the struggles ...]]></description><link>https://blog.taditdash.com/getting-started-on-microservices-with-net</link><guid isPermaLink="true">https://blog.taditdash.com/getting-started-on-microservices-with-net</guid><category><![CDATA[Microservices]]></category><category><![CDATA[Microsoft]]></category><category><![CDATA[dotnet]]></category><category><![CDATA[dotnetcore]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Mon, 01 Nov 2021 12:09:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1635577683478/O-WoSI3wy.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will go through my first experience in trying out Microservices with .NET 5. Though it looks very easy from the <a target="_blank" href="https://dotnet.microsoft.com/learn/aspnet/microservice-tutorial/intro">official documentation</a>, however, I am documenting my experience as I was following through. I will explain the struggles and how I found the solutions to different issues.</p>
<h1 id="the-prerequisites">The Prerequisites 🔧</h1>
<p>As I said that I followed the official documentation, you can follow that to start up. Here are things you will definitely need to have in your system.</p>
<ol>
<li><a target="_blank" href="https://download.visualstudio.microsoft.com/download/pr/8a504918-9508-464d-80c6-4da7f9cc9ac6/f9d6ad00bbd798bafb549101b5b4a4c0/dotnet-sdk-5.0.402-win-x64.exe">.NET SDK</a></li>
<li><a target="_blank" href="https://docs.docker.com/desktop/">Docker</a></li>
</ol>
<h1 id="lets-get-started">Let's get started 👇</h1>
<p>If .NET SDK is installed successfully, running the following command will show the version of .NET installed. In my case at the point of writing this blog, it is <code>5.0.402</code>.</p>
<pre><code>dotnet <span class="hljs-comment">--version</span>
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635582457449/PF5J8zt00.png" alt="dotnet version.png" />
Now let's try to see if docker is ready or not. </p>
<pre><code>docker <span class="hljs-comment">--version</span>
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635585345789/60Ewv0hzz.png" alt="docker version.png" /></p>
<p>Now as mentioned in the tutorial, let's build a microservice using <code>dotnet</code> command.</p>
<pre><code>dotnet <span class="hljs-built_in">new</span> webapi -o MyMicroservice <span class="hljs-comment">--no-https -f net5.0</span>
</code></pre><p>Here we are instructing to create a webapi project inside <code>MyMicroservice</code> directory with no https certificate as we are keeping things simple. Notice the framework mentioned in the command as <code>net5.0</code>.
We exactly get what we asked for. Let's have a look at the directory.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635593734947/uDC7niGuN.png" alt="Dotnet WebAPI Project.png" /></p>
<p>This is a scaffolded project with some autogenerated code. Notice the <em>WeatherForecastController.cs</em> inside <em>Controllers</em> directory. This is one such class that exposes one endpoint in the format of controller name without the "Controller" word, here it is <code>/weatherforecast</code>.</p>
<p>Inside this controller, the thing we care about for now is the method <code>Get()</code> that is going to return a list of random weather data. You can open and analyse the code which is self explanatory.</p>
<pre><code>[HttpGet]
<span class="hljs-built_in">public</span> IEnumerable&lt;WeatherForecast&gt; <span class="hljs-keyword">Get</span>()
{
    var rng = <span class="hljs-built_in">new</span> Random();
    <span class="hljs-keyword">return</span> Enumerable.Range(<span class="hljs-number">1</span>, <span class="hljs-number">5</span>).<span class="hljs-keyword">Select</span>(<span class="hljs-keyword">index</span> =&gt; <span class="hljs-built_in">new</span> WeatherForecast
    {
        <span class="hljs-type">Date</span> = DateTime.Now.AddDays(<span class="hljs-keyword">index</span>),
        TemperatureC = rng.Next(<span class="hljs-number">-20</span>, <span class="hljs-number">55</span>),
        <span class="hljs-keyword">Summary</span> = Summaries[rng.Next(Summaries.Length)]
    })
    .ToArray();
}
</code></pre><p>Let's now run the Web API and try to see the result on the browser. To run the app, execute the following command inside the project directory.</p>
<pre><code><span class="hljs-attribute">dotnet</span> run
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635591847304/O47Ct9ImM.png" alt="dotnet run.png" />
Successful! Let's open the URL (as mentioned in the screenshot above) on a browser tab.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635592078186/pxWZ0l4fu.png" alt="image.png" />
Alright, we are good and our app is ready. In the next section, we will set up docker.</p>
<h1 id="docker">Docker 📦</h1>
<p>Docker helps us to package our app and configuration into an independently deployable unit otherwise called a container. Let's do that and see how that works out for us.
If you have downloaded docker and checked the version then well and good. If not, now is the time to do that.</p>
<h2 id="dockerfile">Dockerfile</h2>
<p>I assume you have done that now while reading this sentence. Let's now instruct docker about our app and how that can run by providing information in a file name as <em>Dockerfile</em> inside the project folder with the following contents.</p>
<pre><code><span class="hljs-keyword">FROM</span> mcr.microsoft.com/dotnet/sdk:<span class="hljs-number">5.0</span> <span class="hljs-keyword">AS</span> build
WORKDIR /src
<span class="hljs-keyword">COPY</span> MyMicroservice.csproj .
RUN dotnet restore
<span class="hljs-keyword">COPY</span> .  .
RUN dotnet publish -c <span class="hljs-keyword">release</span> -o /app

<span class="hljs-keyword">FROM</span> mcr.microsoft.com/dotnet/aspnet:<span class="hljs-number">5.0</span>
WORKDIR /app
<span class="hljs-keyword">COPY</span> <span class="hljs-comment">--from=build /app .</span>
ENTRYPOINT ["dotnet", "MyMicroservice.dll"]
</code></pre><p>This file would help the docker daemon to build an image out of these instructions. Know more about the structure of this file <a target="_blank" href="https://docs.docker.com/engine/reference/builder/">here</a>.</p>
<p>The docker daemon is a part of the docker engine. It is a self-sufficient runtime that manages Docker objects such as images, containers, networks, and storage.</p>
<p>Let's understand the instructions used in the Dockerfile.</p>
<h3 id="from-instruction"><code>FROM</code> Instruction</h3>
<p>This file starts with a <code>FROM</code> instruction by providing a parent image. Here, the parent image needed is Microsoft's official dotnet SDK 5.0. You can see the details of this image at <a target="_blank" href="https://hub.docker.com/_/microsoft-dotnet-sdk">docker hub</a>. All docker images published by Microsoft can be browsed <a target="_blank" href="https://hub.docker.com/publishers/microsoftowner">here</a>.</p>
<p>Moreover, a name can be provided to a new build stage with <code>AS</code> to the <code>FROM</code> instruction. This name can be used in subsequent instructions like <code>FROM</code> and <code>COPY --from=&lt;name&gt;</code> to refer to the image built.</p>
<h3 id="workdir-instruction"><code>WORKDIR</code> Instruction</h3>
<p>This is responsible for setting up a directory for subsequent commands like <code>RUN</code>, <code>COPY</code>, etc.</p>
<h3 id="copy-instruction"><code>COPY</code> Instruction</h3>
<p>The syntax is <code>COPY &lt;source&gt; &lt;destination&gt;</code>. In our case, we need to take all required resources inside the container so that we can build and run our app.</p>
<p>The instruction <code>COPY MyMicroservice.csproj .</code> indicates copying our project configuration file present inside the project directory to the destination <em>/src</em> folder that we have created just before this instruction. However, here we have mentioned a <strong>dot (.)</strong> instead of <em>/src</em> because we have already mentioned the <code>WORKDIR</code> as <em>/src</em>, so <strong>dot (.)</strong> will point to the relative path with respect to the <code>WORKDIR</code>.</p>
<p>There is a <code>COPY . .</code> command also used in our code that says to copy all our codes (first dot) into the <code>WORKDIR</code> (second dot).</p>
<h2 id="run-instruction"><code>RUN</code> Instruction</h2>
<p>This instruction can be used to run a command. <code>RUN dotnet restore</code> helps to restore all packages needed for out project.</p>
<p>With <code>RUN dotnet publish -c release -o /app</code> we are publishing our app with release configuration into the directory <em>/app</em> inside the container.</p>
<h2 id="entrypoint-instruction"><code>ENTRYPOINT</code> Instruction</h2>
<p>Provides the commands to configure the container as an executable that can be invoked by docker commands.</p>
<p>So, basically, the first set of instructions is used to do the following.</p>
<ol>
<li>Takes <code>mcr.microsoft.com/dotnet/sdk:5.0</code> as the parent image</li>
<li>Creates a <em>/src</em> directory inside the container</li>
<li>Copies project configuration file</li>
<li>Restores packages</li>
<li>Copy all our codes into the <em>/src</em> directory</li>
<li>Publish the project to a directory <em>/app</em> with release configuration </li>
</ol>
<p>The second set of instructions is for the following.</p>
<ol>
<li>Takes the parent image as the ASP.NET Core runtime image <code>mcr.microsoft.com/dotnet/aspnet:5.0</code></li>
<li>Sets WORKDIR as <em>/app</em></li>
<li>Copies all published artifacts from the previous stage</li>
<li>Executes the <code>dotnet MyMicroservice.dll</code> command to run the app</li>
</ol>
<p><strong>NOTE:</strong> When we copied all files from our project to the container in the first stage, we should exclude the <code>Dockerfile</code>, <code>bin</code>, and <code>obj</code> folders. To do that, we can add a <code>.dockerignore</code> file. Here is what it would look like.</p>
<pre><code><span class="hljs-selector-tag">Dockerfile</span>
<span class="hljs-selector-attr">[b|B]</span><span class="hljs-selector-tag">in</span>
<span class="hljs-selector-attr">[O|o]</span><span class="hljs-selector-tag">bj</span>
</code></pre><p>At this point, the following screenshot of the project directory is what you should be having.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635669144214/M4mk2F27a.png" alt="Microservice with Dockerfile and Docker Ignore.png" /></p>
<h1 id="lets-build-an-image-using-docker">Let's build an image using Docker 👨‍🏭</h1>
<p>Now that our <em>Dockerfile</em> is ready with instructions, let's build an image using <code>docker build</code> command. A docker image is just a file (behaves as a template) used to execute codes inside the docker container. This image contains our application code, libraries, tools, dependencies, and other files required to make the application run. When an image is run using <code>docker run</code> command, it becomes one or many instances of a container.</p>
<p>Here we go.</p>
<pre><code><span class="hljs-attribute">docker</span> build -t mymicroservice .
</code></pre><p>Here <code>-t</code> helps to tag the image with a name, in our case it is <code>mymicroservice</code> so that we can refer to this image afterwords. The final parameter (dot) tells it which directory to use to find the Dockerfile. Here dot refers to the current directory as we are running this command inside the project directory. This command downloads and builds all dependencies to create a Docker image that we will use to run a container.</p>
<p>Let's hit enter. Not what we expected. You might see an error like the below where it is mentioned that no such <code>Dockerfile</code> is found. 
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635695612819/mG3zYjibV.png" alt="Docker Build Unsuccessful Dockerfile not found.PNG" />
This happened to me due to a silly mistake with a letter casing <strong>F</strong> that made the file name <code>DockerFile</code>, but it should be 'Dockerfile'.</p>
<p>Alright, let's move on. Here is what you would see if the <code>Dockerfile</code> is correct and found.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635696141638/ILccHQqpj.png" alt="Docker Daemon Not Running.PNG" /></p>
<p>Oops! One more error. 😢😢😢 No issues. It says to start docker. Let's do that. Just searched from available apps in the system and ran. Here is what I see.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635696935513/ahcbrd_S_.png" alt="Docker Engine Failed to Start.PNG" /></p>
<p>The docker engine failed to start. Interesting! 🤦‍♂️ My date is getting a little frustrating! 🙁</p>
<p>Oh, I remember, doh! I intentionally skipped one step to see what error I would get going forward. That step is the system restart after docker installation. Let me do that quickly.</p>
<p>The following windows alert confirms my suspicion.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635745292226/6ZSDSXr7k.png" alt="Docker Requires Logout.PNG" /></p>
<p>You might also notice a red docker icon on the system tray like mine.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635745431499/LRFIj8ljj.png" alt="Docker on System Tray.PNG" /></p>
<p>Alright, the system is restarted. Now trying to open docker again. I see this now.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635745705331/oqCb-io9B.png" alt="Unhandled Exception.PNG" /></p>
<p>It mentions something like <strong>WSL2</strong>. Let's click on the "Continue" button as we want to see the information behind this error.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635745883820/jyLcAePMQ.png" alt="WSL 2 Linux Kernel Installation.PNG" />
<a target="_blank" href="https://docs.docker.com/desktop/windows/wsl/">WSL2</a> is a Linux kernel built by Microsoft, that allows Linux containers to run natively without emulation.</p>
<p>As asked, let's install that from <a target="_blank" href="https://aka.ms/wsl2kernel">here</a>. Download, run the setup and follow the next -&gt; next process to complete.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635746272594/e6hnQ7iV0.png" alt="Windows Subsystem for Linux Update Setup.PNG" /></p>
<p>Now that we are ready with docker and WSL 2, let's rerun the docker app which would in return ask us to accept the service agreement. Let's accept and move on.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635746355684/JBPFC1yfi.png" alt="Docker Service Agreement.PNG" /></p>
<p>Still not done. Now you might see a firewall network access request. Something like below.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635746401116/zNLNxP6Zg.png" alt="Docker asking for Firewall network access.PNG" /></p>
<p>You can allow access here or to make it more interesting close this pop-up in order to struggle a bit again. I did that and then found out how to enable firewall network access for docker. Here is how.</p>
<ol>
<li>Search for Windows Defender Firewall from the windows menu and then click on "Allow an app or feature through Windows Defender Firewall".
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635747128358/H4cmkl_wr.png" alt="Windows Defender Firewall Allow an app or feature.PNG" /></li>
<li>Scroll down inside the list of the available apps, find out and check the "Docker Desktop Backend" checkbox.</li>
<li>Check the checkboxes for Public and Private options for this app.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635747381842/sqZ0tATu0.png" alt="Windows Defender Firewall Docker Desktop Backend.PNG" /></li>
<li>Click the "OK" button to save the settings.</li>
</ol>
<p>Awesome, let's open the docker app again. Here is what we should see with a "No containers running" message which means there is no more configuration error.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635747487945/PMIvIKMwS-.png" alt="Docker Desktop Running Successfully.PNG" /></p>
<p>However, no containers are running as well. That is expected as we have not yet run our container. Let's do that next, but before that let's rebuild the image as it failed initially.</p>
<pre><code><span class="hljs-attribute">docker</span> build -t mymicroservice .
</code></pre><p>With this command, the process has started and you should see these messages on the command prompt.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635747752788/1Vi6-vACn.png" alt="Docker Build Started.PNG" /></p>
<p>Done. No errors anymore on the command prompt. The image is built successfully.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635747771668/1Kq3V8-BV.png" alt="Docker Build Complete.PNG" /></p>
<p>Beautiful. Now let's verify whether the image exists by executing the following command.</p>
<pre><code><span class="hljs-attribute">docker</span> images
</code></pre><p>Awesome, we see our image listed, here is the screenshot.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635748605607/T2Qz72ztj.png" alt="Docker Images.PNG" /></p>
<p>Let's run a container using this image.</p>
<h1 id="run-the-docker-container">Run the Docker Container 🏃‍♂️</h1>
<p>Let's run the image to create a container using the command mentioned below. Let's understand all that is coded here one by one.</p>
<pre><code><span class="hljs-attribute">docker</span> run -it --rm -p <span class="hljs-number">3000</span>:<span class="hljs-number">80</span> --name mymicroservicecontainer mymicroservice
</code></pre><ul>
<li><code>docker run</code> is the command used to run an image</li>
<li><code>-it</code> flag tells Docker to allocate a virtual terminal session within the container. This is commonly used with the <code>-i</code> (or --interactive) option, which keeps STDIN open</li>
<li><code>--rm</code> flag tells the Docker Daemon to clean up the container and remove the file system after the container exits</li>
<li><code>-p</code> maps a single port for the container</li>
<li><code>--name</code> is used to identify a container</li>
<li><code>mymicroservice</code> is the image that we have created earlier</li>
</ul>
<p>Hit enter and let's see what happens.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635753745133/poRLWDuun.png" alt="Docker Run.PNG" /></p>
<p>Wow, it says application is started. Let's open the URL and verify <code>http://localhost:3000/weatherforecast</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635755088369/1spvQgJ5q.png" alt="App running with Docker.PNG" /></p>
<p>Beautiful. We can also verify running containers information with the following command.</p>
<pre><code><span class="hljs-attribute">docker</span> ps
</code></pre><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635767452027/Uxo-wLfAq.png" alt="Docker PS.PNG" /></p>
<p>Inside docker for windows app, we can also see our container displayed with a running status on port 3000.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635767500478/H3CRTDTyB.png" alt="App running on Docker Desktop.PNG" /></p>
<p>If we click on this container, we can see the details of the running container similar to what we saw after we ran the <code>docker run</code> command.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1635767683085/Wp5tlarB_.png" alt="Docker Desktop App Details View.PNG" /></p>
<h1 id="next-steps">Next steps ⏭</h1>
<p>So, finally the microservice is ready and running inside of a docker container that is independently deployable on any platform without any external configurations. In the next blog, we will see how we can deploy this to a cloud provider.</p>
<h1 id="feedback">Feedback 🙌</h1>
<p>Let me know what you feel about this blog. If you like what you read, please share in your circle and click on "Buy me a Coffee" because I love coffee. ☕😍</p>
]]></content:encoded></item><item><title><![CDATA[Do you know that null is an object in JavaScript?]]></title><description><![CDATA[Interesting, isn't it? In JavaScript, null is an object. Here is the screenshot from Chrome Developer Tool.

Background ◀️
I have started reading You Don't Know JS by Mr. Kyle Simpson and in chapter 2, I got to know something interesting about null t...]]></description><link>https://blog.taditdash.com/do-you-know-that-null-is-an-object-in-javascript</link><guid isPermaLink="true">https://blog.taditdash.com/do-you-know-that-null-is-an-object-in-javascript</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[webdev]]></category><category><![CDATA[#codenewbies]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[web]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Thu, 23 Sep 2021 06:17:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1632413598552/n6GkH0shH.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Interesting, isn't it? In JavaScript, <code>null</code> is an <code>object</code>. Here is the screenshot from <em>Chrome Developer Tool</em>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632410402713/LWPYGKvKv.png" alt="JavaScript-null-is-object.png" /></p>
<h2 id="heading-background">Background ◀️</h2>
<p>I have started reading <em>You Don't Know JS</em> by <a target="_blank" href="https://github.com/getify">Mr. Kyle Simpson</a> and in <a target="_blank" href="https://github.com/getify/You-Dont-Know-JS/blob/1st-ed/up%20%26%20going/ch2.md">chapter 2</a>, I got to know something interesting about <code>null</code> that I wanted to share in a quick blog with all of you.</p>
<h2 id="heading-why">Why? 😮</h2>
<p>The built-in types available in JavaScript are as follows.</p>
<ul>
<li><code>string</code></li>
<li><code>number</code></li>
<li><code>boolean</code></li>
<li><code>null</code> and <code>undefined</code></li>
<li><code>object</code></li>
<li><code>symbol</code></li>
</ul>
<p>To know the type of data, we can use one operator called <code>typeof</code>. This operator when used with data yields the type of that data. Let's try to find out if we get types correctly for different types of data.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/taditdash/pen/GRoxxGK">https://codepen.io/taditdash/pen/GRoxxGK</a></div>
<p>On the CodePen (<a target="_blank" href="https://codepen.io/taditdash/pen/GRoxxGK">https://codepen.io/taditdash/pen/GRoxxGK</a>) embedded above, it clearly shows an appropriate type for different data types except for <code>null</code>. This is weird but true.</p>
<p>Actually, this is a bug and it is like this from the beginning. Now, this can't be fixed as a lot of code is depending on it for a long time. If this is going to be fixed, it will definitely break in legacy apps.</p>
<h2 id="heading-let-me-know">Let me know! 🙏</h2>
<p>What do you think? Do you think it is a feature or a bug? How have used this as an advantage?</p>
<h2 id="heading-stay-updated">Stay Updated 📧  📰</h2>
<p>If you enjoyed reading the blog and you would like to see more of such blogs in the future, do <em>"Subscribe to my newsletter and never miss my upcoming articles"</em> that you see here on top of this page.</p>
<h2 id="heading-updates">Updates 👍</h2>
<p>After I posted this blog on social media, I got one reply from one of the most popular Gurus <a target="_blank" href="https://twitter.com/SanjayVyas">Mr. Sanjay Vyas</a>, who is well known for his unique style of teaching with concept visualization. Here is his website - <a target="_blank" href="https://conceptvisuals.in/">https://conceptvisuals.in/</a></p>
<p>Here is the screenshot from Twitter.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1632410629954/8nmseY0FT.png" alt="Mr.-Sanjav-Vyas-Reply.png" /></p>
<p>This means <code>null</code> looks like an object, however, it does not have the characteristics. This brings a lot of value to its implementation where the developer can design the code keeping these caveats in mind.</p>
<p>This is the beauty of the community, where like-minded people share knowledge between themselves. I am very lucky to be a part of the tech community where I am meeting people like Sanjay Sir every day.</p>
<p>Thank you Sanjay Sir and everyone who read this blog. Have a nice day. 😃</p>
]]></content:encoded></item><item><title><![CDATA[Vuetify Clear Fields on Dialog Open]]></title><description><![CDATA[In this blog, we will look into a simple technique to clear out fields when dialog or modal is opened in an application using Vue and Vuetify.
Background
This is very common to open a dialog or modal from a page. Often is the case where we load data ...]]></description><link>https://blog.taditdash.com/vuetify-clear-fields-on-dialog-open</link><guid isPermaLink="true">https://blog.taditdash.com/vuetify-clear-fields-on-dialog-open</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[modal]]></category><category><![CDATA[vue]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Fri, 17 Sep 2021 06:17:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631884645364/7cYe7XXpl.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will look into a simple technique to clear out fields when dialog or modal is opened in an application using Vue and Vuetify.</p>
<h2 id="heading-background">Background</h2>
<p>This is very common to open a dialog or modal from a page. Often is the case where we load data on the controls inside modal based on values passed from the parent page. That is where it also comes with a requirement to clear out fields whenever the modal is opened from the parent page. We will tackle this problem in this blog.</p>
<h2 id="heading-lets-understand-the-problem">Let's understand the problem</h2>
<p>First thing first, let's write the HTML for the popup and property to manage the show/hide of the modal.</p>
<pre><code>&lt;v-dialog v-model=<span class="hljs-string">"showDialog"</span> width=<span class="hljs-string">"500"</span>&gt;
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">v-card</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">v-card-title</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"headline"</span>&gt;</span>A Form<span class="hljs-tag">&lt;/<span class="hljs-name">v-card-title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">v-card-text</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">v-text-field</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"First Name"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"firstName"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">v-text-field</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">v-text-field</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Last Name"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"lastName"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">v-text-field</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">v-text-field</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Email"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"email"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">v-text-field</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">v-select</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Profession"</span> <span class="hljs-attr">:items</span>=<span class="hljs-string">"professionItems"</span> <span class="hljs-attr">v-model</span>=<span class="hljs-string">"profession"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">v-select</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">v-card-text</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">v-card-actions</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">v-spacer</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">v-spacer</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"green darken-1"</span> <span class="hljs-attr">text</span> @<span class="hljs-attr">click</span>=<span class="hljs-string">"showDialog = false"</span>&gt;</span>Close<span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">v-card-actions</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">v-card</span>&gt;</span></span>
&lt;/v-dialog&gt;
</code></pre><p>Notice the code and keep reading the following points.</p>
<ol>
<li>The first thing we need to make sure is the dialog component accepting a boolean property named <code>showDialog</code>, that controls the visibility of the popup. That means if <code>showDialog = true</code>, then popup shows, else, it is hidden.</li>
<li>I have added three text fields for <em>First Name</em>, <em>Last Name</em>, and <em>Email</em>. One select box is there for the <em>Profession</em>. All these fields have their respective model properties mentioned in the <code>v-model</code> directive.</li>
<li>Then there is one button inside the popup to close it when clicked. Obviously, it is going to set <code>false</code> to the <code>showDialog</code> property as I said in point number 1.</li>
</ol>
<p>The last important piece is to add a button to this codebase in order to open the popup. The following <code>v-btn</code> can do the task for us by doing <code>showDialog = true</code> on the click event.</p>
<pre><code>&lt;v-btn @click=<span class="hljs-string">"showDialog = true"</span>&gt;Open Modal&lt;/v-btn&gt;
</code></pre><p>So, let's click on this button, that will bring up the popup, that looks something like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1630218543083/FjbFneSPB.png" alt="v-dialog-Example-Tadit-Dash-1-1024x851.png" /></p>
<p>I have entered my details in the controls. Now, I will click on the button "Close", which will just close the dialog by setting <code>false</code> in <code>showDialog</code> property.</p>
<p>Now, if you open this modal again by clicking on the button "Open Modal", you will see all the values as entered by you. However, my requirement was to clear out all these fields and it would depend upon your situation and project. So, let's see how we can do that.</p>
<h2 id="heading-solution">Solution</h2>
<p>This problem can be easily solved if you just clear out all these fields, just before the popup is opened, isn't it? The popup show/hide is managed by the property showDialog. That means, when <code>showDialog</code> is set to <code>true</code> (for opening the popup), we have to clear out the fields.</p>
<p><strong>Logic:</strong> showDialog = true -&gt; Clear out the fields</p>
<p>Here comes a <code>watcher</code>. We need to watch the <code>showDialog</code> property. Inside the watcher, if the value is <code>true</code>, meaning if the user is trying to open the modal by clicking the "Open Modal" button, let's remove the field values. The watcher would look something like below.</p>
<pre><code>watch: {
    <span class="hljs-attr">showDialog</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">val</span>) </span>{
      <span class="hljs-keyword">if</span>(val) {
        <span class="hljs-built_in">this</span>.firstName = <span class="hljs-string">''</span>;
        <span class="hljs-built_in">this</span>.lastName = <span class="hljs-string">''</span>;
        <span class="hljs-built_in">this</span>.email = <span class="hljs-string">''</span>;
        <span class="hljs-built_in">this</span>.profession = <span class="hljs-string">''</span>;
      }
    }
  }
</code></pre><p>Notice how we are making all the properties blank so it would automatically reflect on the controls associated with them through <code>v-model</code>.</p>
<h2 id="heading-full-source-code-with-demo-on-codepen">Full Source Code with Demo on CodePen</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/taditdash/pen/dyGbZjB">https://codepen.io/taditdash/pen/dyGbZjB</a></div>
<h2 id="heading-feedback">Feedback</h2>
<p>Sharing is caring! If you loved this blog, feel free to share in your circle, you can do this by clicking the share icon.</p>
<p>Comments are appreciated as always. :)</p>
<h2 id="heading-it-takes-7-days-to-learn-vuejs">It takes 7 Days to learn Vue.js</h2>
<p>Yes, you heard that right. I have co-authored a book that comprehensively takes you on a 7 days journey to learn the basics of Vue.js. You can buy that from <a target="_blank" href="https://www.amazon.com/gp/product/9388511867/ref=dbs_a_def_rwt_bibl_vppi_i1">Amazon.com</a> or <a target="_blank" href="https://www.amazon.in/Learn-Vue-js-Days-Journey-through/dp/9388511867/ref=tmm_pap_swatch_0?_encoding=UTF8&amp;qid=&amp;sr=">Amazon.in</a> or <a target="_blank" href="https://bpbonline.com/products/learn-vue-js-in-7-days">BPB Official Website</a>.<br />More at - <a target="_blank" href="https://taditdash.com/#Vuejs7Days">https://taditdash.com/#Vuejs7Days</a></p>
]]></content:encoded></item><item><title><![CDATA[Configure Vee Validate for Localisation using Vue I18N Library]]></title><description><![CDATA[In this blog, we will learn how to configure vee-validate library so that it would work for translations with the internationalization library vue-i18n.
Background
I am working on a project that is built with Vue.js and set up for internationalizatio...]]></description><link>https://blog.taditdash.com/configure-vee-validate-for-localisation-using-vue-i18n-library</link><guid isPermaLink="true">https://blog.taditdash.com/configure-vee-validate-for-localisation-using-vue-i18n-library</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[localization]]></category><category><![CDATA[vue-i18n]]></category><category><![CDATA[vee-validate]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Wed, 15 Sep 2021 14:34:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631645149871/9k2P75NkX.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this blog, we will learn how to configure <code>vee-validate</code> library so that it would work for translations with the internationalization library <code>vue-i18n</code>.</p>
<h1 id="heading-background">Background</h1>
<p>I am working on a project that is built with Vue.js and set up for internationalization with <code>vue-i18n</code> library. The validations are done with the help of <a target="_blank" href="https://vee-validate.logaretm.com/v4/">vee-validate</a> library that provides out-of-the-box validations for different types of validations like required fields, minimum length, maximum length, etc.</p>
<p>The project is working perfectly. It has a certain code to read the translations from the JSON files inside the <em>src/locales</em> directory.</p>
<p>I did follow this <a target="_blank" href="https://lokalise.com/blog/vue-i18n/">article</a> from lokalise to set up everything.</p>
<h1 id="heading-assumptions">Assumptions</h1>
<p>I will make some assumptions as this is not a beginner write-up. Here is the list of assumptions on a project that you might have already built.</p>
<ol>
<li><p>Vue.js is setup and running</p>
</li>
<li><p>Vee-Validate library is integrated for validations</p>
</li>
<li><p>Vue-I18N library is set up for translations</p>
</li>
<li><p>JSON files for translations are available inside the directory <strong>src/locales</strong> with key and value structure</p>
</li>
</ol>
<h1 id="heading-problem">Problem</h1>
<p>Now the challenge is to include the <code>vee-validate</code> validation message translations to work seamlessly with <code>vue-i18n</code> library. When I say validation messages then it contains two things.</p>
<ol>
<li><p>The field name that we are validating</p>
</li>
<li><p>The validation message according to the validation type</p>
</li>
</ol>
<p>Let's go through the following examples to understand the above points.</p>
<p>Let's say we have a <strong>First Name</strong> field that is required. So, the validation message that would show when you don't enter anything would be something like the below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631592279306/Ph4yeusFE.png" alt="The First Name field is required.png" /></p>
<p>Here, if we want to translate the validation messages, then we have to translate the field (<code>First Name</code>) and then the validation message (<code>The {field} field is required</code>). Essentially the field is a variable here.</p>
<p>Now you must be thinking why can't we just have the translations for the whole string, that is because there might be a lot of fields in your whole project. Moreover, the validations messages are not just for required fields. These messages can be a lot complicated.</p>
<p>Just Imagine a <code>password</code> field with the following setup for validations.</p>
<ol>
<li><p>It is required</p>
</li>
<li><p>It can contain different types of characters</p>
</li>
<li><p>It should be more than 8 chars and less than 13 characters</p>
</li>
</ol>
<p>In this case, there will be different messages and it is totally not scalable to have translations of the whole messages. That's why the field names should be translated and stored in JSON files that we already have. However, no need to translate the validation messages except the field name because the library is already having them for all language types.</p>
<p>For <code>vee-validate</code>, we can see the translated validation messages inside the <em>node-modules/vee-validate/dist/locales</em>.</p>
<h1 id="heading-solution">Solution</h1>
<p>Let's discuss how to solve this problem. When you work with <code>vue-i18n</code> library, there will be some code that would be auto-generated when you install the package using the <code>vue-cli</code> command <code>vue add i18n</code>. You can follow the lokalise <a target="_blank" href="https://lokalise.com/blog/vue-i18n/">article</a> for details. I will focus on our specific problem. So, one of that scaffolded files is <em>src/i18n.js</em>. Let's have a sneak peek.</p>
<pre><code class="lang-plaintext">// src/i18n.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

function loadLocaleMessages () {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  const messages = {}
  locales.keys().forEach(key =&gt; {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i)
    if (matched &amp;&amp; matched.length &gt; 1) {
      const locale = matched[1]
      messages[locale] = locales(key)
    }
  })
  return messages
}

export default new VueI18n({
  locale: process.env.VUE_APP_I18N_LOCALE || 'en',
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})
</code></pre>
<p>Essentially we are trying to import <code>Vue</code> and <code>VueI18n</code> libraries so that we can configure the translations.</p>
<p>Notice the function <code>loadLocaleMessages</code> which is helping us to load all messages from the JSON translation files that reside inside the <em>src/locales</em> directory. The code <code>messages[locale] = locales(key)</code> is pulling all our translations from a specific file represented by the key, for example, "./de.json" for German. Then it stores in a property represented by the locale param. Thus, it becomes the object shown below in the screenshot.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631593154408/kNBfhGxWq.png" alt="Translation Messages Object View.png" /></p>
<p>And it continues to add properties with the locale names to this object as it loops through all locales.</p>
<p>At last, a VueI18n is exported containing the locale from the <code>.env</code> file or default one as <code>'en'</code>, also a <code>fallbackLocale</code> and the <code>messages</code> that we just retrieved from the JSON files.</p>
<p>Now the interesting part. We need to integrate the <code>vee-validate</code> messages. Let's see the problem in the first place with the screenshot below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631592368236/kSdKOg9Vb.png" alt="The First Name field is required 2.png" /></p>
<p>As you can see here, the First Name label is now changed to <strong>Nombre</strong> for the Spanish language (Imagine I have a language switcher with different languages), however, the validation message is still in English. That is what we need to fix. Let's find a way.</p>
<p>We already discussed a simple logic of splitting the validation message into two parts. <code>The First Name field is required</code> follows a patern <code>The {_field_} field is required</code> where <code>{_field_}</code> is <strong>First Name</strong>.</p>
<p>Now somehow we need to code for two things.</p>
<ol>
<li><p>Ask <code>VueI18n</code> to include all the validation messages for all languages</p>
</li>
<li><p>Replace <code>{_field_}</code> with the field name translation from our translation files</p>
</li>
</ol>
<h2 id="heading-ask-vuei18n-to-include-all-the-validation-messages-for-all-languages">Ask <code>VueI18n</code> to include all the validation messages for all languages</h2>
<p>It is a bit tricky till I figured out the solution. It's totally my hack. Let's see how we can do. Obviously, we have to do something where all the translations are fetched. Do you remember where?</p>
<p>Yes, it's our well-known <code>loadLocaleMessages()</code>. Let's make some modifications.</p>
<pre><code class="lang-plaintext">// src/i18n.js

function loadLocaleMessages () {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  const messages = {}

  locales.keys().forEach(key =&gt; {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i)
    if (matched &amp;&amp; matched.length &gt; 1) {
      const locale = matched[1]
      messages[locale] = locales(key)

      // Load the validation messages from vee-validate 
      // library into the messages object.
      messages[locale].validation = getVeeValidateLocale(locale).messages
    }
  })
  return messages
}

function getVeeValidateLocale (locale) {
  // Get validation messages from vee-validate locale file.
  // If locale 'en', then get the messages from "vee-validate/dist/locale/en.json"
  // If locale 'es', then get the messages from "vee-validate/dist/locale/de.json"
}
</code></pre>
<p>Notice that we have a new code inside the <code>forEach</code> that will fetch the validation messages according to the locale that we are looping and then place it as a validation property of the messages locale object. We will see it in a while. Just stay with me a little bit.</p>
<p>That means here we need to somehow ask <code>vee-validate</code> library to give us the translated validation messages. To do that, we have to do the following.</p>
<ol>
<li><p>Import the validation JSON files containing the translated messages</p>
</li>
<li><p>Get the validation messages for the particular locale that is passed to the <code>getVeeValidateLocale()</code>.</p>
</li>
</ol>
<p>Let's complete these one by one.</p>
<h3 id="heading-import-the-validation-json-files-containing-the-translated-messages">Import the validation JSON files containing the translated messages</h3>
<p>For importing, we can write the import statements like the following.</p>
<pre><code class="lang-plaintext">// src/i18n.js

import en from "vee-validate/dist/locale/en.json" // English validation messages.
import de from "vee-validate/dist/locale/de.json" // German validation messages. 
import es from "vee-validate/dist/locale/es.json" // Spanish validation messages.

// ... Import statements for other languages
</code></pre>
<p>Don't trust me on here about the translated validation messages! Let me give you a quick look at one of these files. Here is the <em>es.json</em> file that is available from <code>vee-validate</code>.</p>
<pre><code class="lang-plaintext">// node_modules/vee-validate/dist/locale/es.json

{
  "code": "es",
  "messages": {
    // ... removed for brevity

    "email": "El campo {_field_} debe ser un correo electrónico válido",

    "max": "El campo {_field_} no debe ser mayor a {length} caracteres",
    "max_value": "El campo {_field_} debe de ser {max} o menor",

     // ... removed for brevity

    "numeric": "El campo {_field_} debe contener solo caracteres numéricos",
    "regex": "El formato del campo {_field_} no es válido",
    "required": "El campo {_field_} es obligatorio",
    "required_if": "El campo {_field_} es obligatorio",
    "size": "El campo {_field_} debe ser menor a {size}KB"
  }
}
</code></pre>
<p>This JSON file is basically a collection of validation messages according to the type of validation.</p>
<p>In here, see the item <code>"required": "El campo {_field_} es obligatorio"</code> which is actually the translated message for the required field type validation message, for instance <code>The {_field_} field is required</code> in English. Here <code>{_field_}</code> is the variable where we will place the translation for the field. We will do that in the next section.</p>
<h3 id="heading-get-the-validation-messages-for-the-particular-locale-that-is-passed-to-the-getveevalidatelocalelocale">Get the validation messages for the particular locale that is passed to the <code>getVeeValidateLocale(locale)</code></h3>
<p>Now that we know where to get the messages from, let's populate some code inside the function <code>getVeeValidateLocale(locale)</code>.</p>
<pre><code class="lang-plaintext">// src/i18n.js

// ... other codes...

function getVeeValidateLocale (locale) {
  if (locale == 'en') {
    return en;
  } else if (locale == 'de') {
    return en;
  } else if (locale == 'es') {
    return es;
  }
  // ...

  return en;
}
</code></pre>
<p>Basically, we are trying to say to return the appropriate imported locale JSON file according to the locale passed as an argument, else default as <em>English (en)</em>. However, clearly, this is not a good approach because <code>if else</code> can make this code unnecessarily long. We can definitely do better than this.</p>
<p>Can we do a <code>switch case</code>? Again, the same kind of code isn't it. We have one more nice option. <strong>Object Literals</strong>. This would definitely minimize the amount of code for this requirement. Let's see.</p>
<pre><code class="lang-plaintext">function getVeeValidateLocale (locale) {
  const veeValidateLocales = {
    'en': en, 
    'de': de,
    'es': es,
    //...
    'default': en
  };

  return veeValidateLocales[locale] || veeValidateLocales['default'];
}
</code></pre>
<p>Simple and clean. An object a declared with a collection of <strong>name-value</strong> pairs. To select a particular item we can select it using the syntax <code>object_name['property name']</code>. You can read more about this at <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects">Working with objects</a>.</p>
<p>This can be optimized more as the name and value are the same except the default one.</p>
<pre><code class="lang-plaintext">// You can add more languages to this object as needed.
function getVeeValidateLocale (locale) {
  const veeValidateLocales = { en, de, es, 'default': en };

  return veeValidateLocales[locale] || veeValidateLocales['default'];
}
</code></pre>
<p>Let's put a debugger now to see how this works at <code>messages[locale].validation = getVeeValidateLocale(locale).messages</code>. Here is the browser console screenshot.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631592538796/BBmYeBxpG.png" alt="Validation Translations.png" /></p>
<p>Beautiful, now we are able to get the translated validation messages. The only thing left here is to replace the <code>{_field_}</code> with the actual translated field name.</p>
<h2 id="heading-replace-field-with-the-field-name-translation-from-our-translation-files">Replace <code>{_field_}</code> with the field name translation from our translation files</h2>
<p>This is easy as we already have the translations for the field names in our JSON files as we see <strong>Nombre</strong> for the First Name field for Spanish. So, we need to just load the same translation for the validation message.</p>
<p>Your translation JSON file for Spanish might look something like this.</p>
<pre><code class="lang-plaintext">// src/locales/es.json

{
    "fieldFirstName": "Nombre"
    // ... other translation keys and values.
}
</code></pre>
<p>That means we just need to find the value of this <code>key</code> for the First Name field as an example. Assuming that you have a running setup of <code>vee-validate</code> with the Vue project, here is the code to update the default messages that can run for every field when validation comes into picture.</p>
<pre><code class="lang-plaintext">// src/main.js

// ... other codes

import { configure } from 'vee-validate'
import * as rules from 'vee-validate/dist/rules'
import i18n from './i18n'

configure({
  defaultMessage: (field, values) =&gt; {
    // Remove whitespace inside the field name
    let fieldName = field.replace(/\s+/g, "");

    values._field_ = i18n.t(`field${fieldName}`);

    return i18n.t(`validation.${values._rule_}`, values);
  }
});

// ... other codes
</code></pre>
<p>This <code>defaultMessage</code> function runs for all fields that become active on the page. Assuming that it is currently running for the field "First Name", let's try to understand line by line.</p>
<ol>
<li><p>The argument <code>field</code> possesses <strong>First Name</strong> (comes from the input tag configuration)</p>
</li>
<li><p><code>let fieldName = field.replace(/\s+/g, "");</code>: This would remove all whitespace inside the field name, so now <code>fieldName</code> is <strong>FirstName</strong></p>
</li>
<li><p>The param <code>values</code> contains the details about the particular validation, see the console output below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631594294669/szknW-hWg.png" alt="The values param inside the vee-validate defaultMessage function.png" /></p>
</li>
<li><p>So, now, we need to translate the <code>values._field_</code> property that we are doing next with the code <code>values._field_ = i18n.t(`field${fieldName}`);</code> The <code>i18n.t()</code> function is used to get the translation for a key, here the key is <code>fieldFirstName</code>. Remember the JSON file I showed above contained this key and its translation for the Spanish language.</p>
</li>
<li><p>Now that we are done with the field name translation, we can now replace the this in the whole validation message that we stored in messages locale's validation property. That is done by <code>i18n.t(`validation.${values._rule_}`, values)</code>. Here the <code>values</code> is a param that is passed to this <code>i18n.t()</code> is responsible for the replacement of <code>{_field_}</code> which is available in the <code>validation.required</code> as <code>_rule_</code> is <strong>required</strong>.</p>
</li>
</ol>
<p>With this, our code is configured to work. Here is how it would look like.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631596018264/WfZEpSarQ.png" alt="Translated validation message.png" /></p>
<p>There is just one last thing you have to do if you have a mechanism to switch the language. You just need to trigger a refresh for the messages as soon as you switch the language, which can be done by calling the <code>localeChanged()</code> from <code>vee-validate</code> library. If you don't do this, the validation message will still be translated but would be lazy and won't show up till you make a mistake.</p>
<p>Here is the example code to fire an immediate change of language when you switch languages.</p>
<pre><code class="lang-plaintext">import { localeChanged } from 'vee-validate';

// ... other codes

switchLocale() {
  if (this.$i18n.locale !== this.selectedLocale.val) {
    this.$i18n.locale = this.selectedLocale.val;
    localeChanged();
  }
}

// ... other codes
</code></pre>
<h1 id="heading-feedback">Feedback</h1>
<p>I hope this blog helps someone in resolving the case of integrating <code>vee-validate</code> with <code>vue-i18n</code>.</p>
<p>In case you face some issues or have some feedback, feel free to add a comment below and I will definitely reply once I see it.</p>
<p>If you find this useful, please share it on your social channels.</p>
<p>Thanks for reading. Have a nice day ahead. 😎</p>
]]></content:encoded></item><item><title><![CDATA[Vuetify Rounded Card Design]]></title><description><![CDATA[The idea is to customize the corners of the v-card component in Vuetify so that it looks rounded. Let's see what is the impediment and how to overcome that easily.
Background
While working on designing a Billing Subscription Box in a current project,...]]></description><link>https://blog.taditdash.com/vuetify-rounded-card-design</link><guid isPermaLink="true">https://blog.taditdash.com/vuetify-rounded-card-design</guid><category><![CDATA[Vue.js]]></category><category><![CDATA[vue]]></category><category><![CDATA[CSS]]></category><category><![CDATA[HTML]]></category><category><![CDATA[Web Development]]></category><dc:creator><![CDATA[Tadit Dash]]></dc:creator><pubDate>Thu, 02 Sep 2021 06:17:49 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1631816299619/vyhNUSPTb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>The idea is to customize the corners of the <code>v-card</code> component in Vuetify so that it looks rounded. Let's see what is the impediment and how to overcome that easily.</p>
<h2 id="heading-background">Background</h2>
<p>While working on designing a Billing Subscription Box in a current project, the requirement was to design rounded corners instead of normal corners.</p>
<h2 id="heading-lets-code">Let's Code</h2>
<p>Let's first have a normal card that would look something like below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631807663389/WATlYYDYc5.png" alt="Normal-Card.png" /></p>
<p>The code is pretty simple, isn't it!</p>
<pre><code><span class="hljs-tag">&lt;<span class="hljs-name">v-card</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">v-card-title</span>&gt;</span>Tadit Dash<span class="hljs-tag">&lt;/<span class="hljs-name">v-card-title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">v-card-subtitle</span>&gt;</span>Tadit Dash is an Indian by heart, a Software Engineer by profession, an Author and a Speaker by passion.<span class="hljs-tag">&lt;/<span class="hljs-name">v-card-subtitle</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">v-card-actions</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span>&gt;</span>mdi-web<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span>&gt;</span>mdi-twitter<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span>&gt;</span>mdi-linkedin<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span>&gt;</span>mdi-facebook<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">v-btn</span> <span class="hljs-attr">icon</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">v-icon</span>&gt;</span>mdi-instagram<span class="hljs-tag">&lt;/<span class="hljs-name">v-icon</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">v-btn</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">v-card-actions</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">v-card</span>&gt;</span>
</code></pre><p>Now let's go to Vuetify Documentation and find out if there is any way to make the corners round. Here it is - <a target="_blank" href="https://vuetifyjs.com/en/components/cards/">https://vuetifyjs.com/en/components/cards/</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631807709219/NLjF0ZIoA.png" alt="v-card-Shaped-Property.png" /></p>
<p>I can see that there is a property named <code>shaped</code>, which helps to add <code>border-radius</code>. That is what we needed. Let's try that and see what happens.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631807816006/mpFujYkPL.png" alt="Shaped-Card.png" /></p>
<p>Wow! We can see the corners are rounded now. However, only the left top and bottom right are having rounded corners. If this is what you need, then your work is done. Copy the code below and enjoy.</p>
<pre><code><span class="hljs-tag">&lt;<span class="hljs-name">v-card</span> <span class="hljs-attr">shaped</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">v-card-title</span>&gt;</span>Tadit Dash<span class="hljs-tag">&lt;/<span class="hljs-name">v-card-title</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">v-card-subtitle</span>&gt;</span>
    <span class="hljs-comment">&lt;!--Removed for brevity--&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">v-card-subtitle</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">v-card-actions</span>&gt;</span>
    <span class="hljs-comment">&lt;!--Removed for brevity--&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">v-card-actions</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">v-card</span>&gt;</span>
</code></pre><p>But I need something else. I wanted all the corners to be rounded which is not possible by default. Then the option here is to do it myself. For that, let's analyze the rendered HTML first.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631815506285/9COC8j3z5.png" alt="v-card-Shaped-Rendered-HTML-1-1024x324.png" /></p>
<p>So, it's quite clear how the corners are getting added under the hood. The following CSS is helping to add a radius at every corner.</p>
<pre><code><span class="hljs-selector-class">.v-card--shaped</span> {
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">24px</span> <span class="hljs-number">4px</span>;
}
</code></pre><p>But it is not uniform. Top Left, Bottom Right is <code>24px</code> and Top Right, Bottom Left is <code>4px</code>. To make it the same across all the corners we need to add the same radius, of course. To do that, we can add a class to the <code>v-card</code> and write CSS rules accordingly.</p>
<pre><code><span class="hljs-tag">&lt;<span class="hljs-name">v-card</span> <span class="hljs-attr">shaped</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"rounded-card mx-auto mt-5"</span> <span class="hljs-attr">max-width</span>=<span class="hljs-string">"344"</span>&gt;</span>
  <span class="hljs-comment">&lt;!--Removed for brevity--&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">v-card</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">style</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text/css"</span>&gt;</span><span class="css">
  <span class="hljs-selector-class">.rounded-card</span> {
      <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">24px</span>;
  }
</span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
</code></pre><p>After this change, the rendered HTML is modified with a radius to all the corners. Screenshot below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1631815398369/wJ8lsWCow.png" alt="v-card-Shaped-Rendered-HTML-with-all-Rounded-Corners-1-1024x321.png" /></p>
<p>The class <code>rounded-card</code> takes over the <code>border-radius</code> property and <code>v-card--shaped</code> is no more applied. The card looks rounded now as all the corners are having a uniform radius. You can increase the radius as per your needs.</p>
<h2 id="heading-here-is-the-codepen">Here is the CodePen</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://codepen.io/taditdash/pen/YzyWQJb">https://codepen.io/taditdash/pen/YzyWQJb</a></div>
<h2 id="heading-help-someone">Help Someone</h2>
<p>Share in your circle. Hit the social icons to share. Keep coding folks. 🙂</p>
<p>Thanks for reading, have a great day ahead.</p>
<h2 id="heading-it-takes-7-days-to-learn-vuejs">It takes 7 Days to learn Vue.js</h2>
<p>Yes, you heard that right. I have co-authored a book that comprehensively takes you in a 7 days journey to learn the basics of Vue.js. You can buy that from <a target="_blank" href="https://www.amazon.com/gp/product/9388511867/ref=dbs_a_def_rwt_bibl_vppi_i1">Amazon.com</a> or <a target="_blank" href="https://www.amazon.in/Learn-Vue-js-Days-Journey-through/dp/9388511867/ref=tmm_pap_swatch_0?_encoding=UTF8&amp;qid=&amp;sr=">Amazon.in</a> or <a target="_blank" href="https://bpbonline.com/products/learn-vue-js-in-7-days">BPB Official Website</a>.<br />More at - <a target="_blank" href="https://taditdash.co.in/#Vuejs7Days">https://taditdash.co.in/#Vuejs7Days</a></p>
]]></content:encoded></item></channel></rss>