<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Mighty ghost hack - Medium]]></title>
        <description><![CDATA[A passionate full-stack developer, Ethical Hacker, Blogger, Youtuber and many more - Medium]]></description>
        <link>https://medium.com/mighty-ghost-hack?source=rss----f5e9a2446544---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Mighty ghost hack - Medium</title>
            <link>https://medium.com/mighty-ghost-hack?source=rss----f5e9a2446544---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 13 Nov 2026 13:32:45 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/mighty-ghost-hack" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Setting Up Charles Proxy with Android Devices and Emulators]]></title>
            <link>https://medium.com/mighty-ghost-hack/setting-up-charles-proxy-with-android-devices-and-emulators-e0d2f62d687f?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/e0d2f62d687f</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[charles-proxy]]></category>
            <category><![CDATA[man-in-the-middle-attack]]></category>
            <category><![CDATA[debugging]]></category>
            <category><![CDATA[debug]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Fri, 27 Mar 2026 06:27:02 GMT</pubDate>
            <atom:updated>2026-03-27T06:27:04.191Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xvVTw33nI-9i8t9y8msn7g.png" /></figure><p>As a Mobile developers, we often need to inspect and debug network calls made by our Android apps — especially when working with APIs.<br>That’s where <strong>Charles Proxy</strong> comes in handy. It acts as a <strong>man-in-the-middle proxy</strong> that helps you capture, analyze, and even modify requests and responses in real-time.</p><p>In this post, I’ll guide you through setting up <strong>Charles Proxy on both Android real devices and emulators</strong>, along with SSL setup for HTTPS debugging.</p><h3>🔧 What You’ll Need</h3><ul><li><strong>Charles Proxy</strong> (<a href="https://www.charlesproxy.com/download/">Download</a>)</li><li>A <strong>computer</strong> (macOS/Windows/Linux) running Charles</li><li><strong>Android device</strong> (physical phone) or <strong>emulator</strong></li><li>Your app or browser that makes API calls</li></ul><h3>🧠 Understanding How Charles Works</h3><p>Charles acts as a proxy between your Android device and the internet.<br>When your device routes traffic through Charles, it captures all outgoing requests and incoming responses.<br>For HTTPS traffic, Charles uses an SSL certificate to decrypt the content — which you must install on your Android device or emulator.</p><h3>📱 Setting Up on an Android Real Device</h3><h4>Step 1: Connect Both Devices to the Same Network</h4><p>Make sure your <strong>Android phone and laptop</strong> are on the same Wi-Fi.</p><p>Now let’s find your computer’s <strong>local IP address directly from Charles.</strong></p><ul><li>Open <strong>Charles Proxy</strong></li><li>Go to the menu <strong>Help → Local IP Address</strong></li><li>Copy the IP address shown (e.g., 192.168.1.5) — this will be your <strong>Proxy Hostname</strong> when configuring the Android Wi-Fi proxy.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/533/1*Cjhyp7cQbEbs-rjkJrUDVw.png" /></figure><h4>Step 2: Configure Charles Proxy Port</h4><p>Let’s configure proxy port, you can change accordingly your port availability.</p><ol><li>Open Charles → go to <strong>Proxy → Proxy Settings</strong></li><li>Note the <strong>HTTP Proxy Port</strong> (default: 8888)</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/603/1*xk5XMOe-xzQWCZylYXKX0w.png" /></figure><h4>Step 3: Set Proxy on Android Device</h4><ol><li>On your phone, open<br> <strong>Settings → Wi-Fi → [Your Network] → Modify Network → Advanced Options</strong></li><li>Set <strong>Proxy = Manual</strong></li><li>Enter: <strong>Proxy Hostname:</strong> your computer’s IP &amp; <strong>Proxy Port:</strong> 8888</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1vjXPwWROrtNdWm2SLQqtA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UC1KcRt5jGWy26COt3ZGsw.png" /></figure><h4>Step 4: Allow Connection in Charles</h4><p>When your phone connects, you’ll see a pop-up in Charles:</p><blockquote><em>“Allow this device to connect?”</em></blockquote><p>✅ Click <strong>Allow</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/804/1*6HLcRkyBmfRXRai_JRzVKg.png" /></figure><h3>Step 5: Install SSL Certificate on Android</h3><ol><li>On your phone, open Chrome and visit:<br> 👉 <a href="http://charlesproxy.com/getssl">http://charlesproxy.com/getssl</a></li><li>A certificate file charles-ssl-proxying-certificate.crt will download.</li><li>Go to <strong>Settings → Security → Install Certificate → CA Certificate</strong></li><li>Select and install the file.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cCVkK10p59oecvd069Q6iA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cexC6E7_PPe_cok1PPeMrw.png" /></figure><p>After this you are good to go, you will able to see traffic in charles proxy.</p><h3>🧩 Setting Up Charles Proxy on Android Emulator</h3><p>Emulators are easier since they share a virtual network with your computer.</p><h4>Step 1: Start Charles and Emulator</h4><p>Make sure Charles is running before you open the emulator.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qX69lkvw6ufYRQ-BlnzInw.png" /></figure><h4>Step 2: Configure Proxy Using ADB</h4><p>Run this in your terminal:</p><pre>adb shell settings put global http_proxy &lt;computer-ip&gt;:8888</pre><p>Example:</p><pre>adb shell settings put global http_proxy 192.168.1.5:8888</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/588/1*iHoEhXDtD63MLr7Lx_POaw.png" /></figure><p>To clear the proxy later:</p><pre>adb shell settings put global http_proxy :0</pre><h4>Step 3: Install SSL Certificate in Emulator</h4><p>Drag and drop the certificate file (charles-ssl-proxying-certificate.pem) into your emulator, or use:</p><pre>adb push charles-ssl-proxying-certificate.pem /sdcard/</pre><p>Then install it via: <strong>Settings → Security → Install Certificate → CA Certificate</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RH3rHg1XJyjaRf2iM3TAag.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*SIw0_jTcCacpbfqvEYdg9w.png" /></figure><h4>That’s it, Now you could see proxy start working</h4><h3>🧪 Verify the Setup</h3><p>Open any app or browser — you should now see network requests in Charles!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/733/1*nh6QzAPIHCMULecXXufIOQ.png" /></figure><p>If HTTPS traffic isn’t decrypted:</p><ul><li>Go to <strong>Proxy → SSL Proxying Settings → Enable SSL Proxying</strong></li><li>Add your target domain(s), e.g. <em>*.api.yourdomain.com *</em>.googleapis.com</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/599/1*1olG26kVA2wPIKZYe8zA_w.png" /></figure><p>In the above attach screenshot, i have hide some urls which are too sensitive to display but you can add you’r own.</p><p>Also, you can quickly enable SSL proxying when you see a request in Charles (under the <em>Structure</em> tab), you can <strong>right-click on the URL</strong> → select <strong>“Enable SSL Proxying”</strong>.</p><p>This automatically adds the domain to your SSL proxying list — no need to open the settings manually.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/328/1*qKqD9lAJnYjB1UyrXyWtOw.png" /></figure><h4>💡 Pro Tips</h4><p>Sometime Android emulators don’t recognize your machine’s local IP (like 192.168.x.x).<br>In that case, use the special Android emulator loopback address instead:</p><pre>adb shell settings put global http_proxy 10.0.2.2:8888</pre><h3>🏁 Conclusion</h3><p>Charles Proxy is an excellent debugging tool - once set up, you can inspect and manipulate all your app’s network calls in real-time.<br>Whether you’re testing APIs, debugging performance, or simulating backend issues, this setup will make your life easier.</p><p>For a detailed guide on setting up Charles Proxy with iOS devices and emulators, check out this article:<br><a href="https://medium.com/@mayurkadampro/bdc2124b6ad9">Setting Up Charles Proxy with iOS Devices and Emulators by Mayur Kadam</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e0d2f62d687f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/setting-up-charles-proxy-with-android-devices-and-emulators-e0d2f62d687f">Setting Up Charles Proxy with Android Devices and Emulators</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setting Up Charles Proxy with iOS Devices and Emulators]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/mighty-ghost-hack/setting-up-charles-proxy-with-ios-devices-and-emulators-bdc2124b6ad9?source=rss----f5e9a2446544---4"><img src="https://cdn-images-1.medium.com/max/2600/1*HgiJS3TPZkxEubfyxrpNwg.png" width="3780"></a></p><p class="medium-feed-snippet">As a Mobile developers, we often need to inspect and debug network calls made by our iOS apps&#x200A;&#x2014;&#x200A;especially when working with APIs.
That&#x2019;s&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/mighty-ghost-hack/setting-up-charles-proxy-with-ios-devices-and-emulators-bdc2124b6ad9?source=rss----f5e9a2446544---4">Continue reading on Mighty ghost hack »</a></p></div>]]></description>
            <link>https://medium.com/mighty-ghost-hack/setting-up-charles-proxy-with-ios-devices-and-emulators-bdc2124b6ad9?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/bdc2124b6ad9</guid>
            <category><![CDATA[ios-apps]]></category>
            <category><![CDATA[ios-development]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[charles-proxy]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Fri, 27 Mar 2026 06:26:41 GMT</pubDate>
            <atom:updated>2026-03-27T06:26:42.644Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[ Make Your App Inclusive: Accessibility Strategies That Every React Native Developer Should Know]]></title>
            <link>https://medium.com/mighty-ghost-hack/make-your-app-inclusive-accessibility-strategies-that-every-react-native-developer-should-know-aaab1fad4228?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/aaab1fad4228</guid>
            <category><![CDATA[accessibility]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[react-native-developers]]></category>
            <category><![CDATA[accessible-design]]></category>
            <category><![CDATA[react-native-development]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Fri, 27 Mar 2026 06:26:08 GMT</pubDate>
            <atom:updated>2026-03-27T06:26:09.419Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*q8ey_d1H1phI0mtqGFX1hw.jpeg" /></figure><h3>🌍 Introduction: More Than Just Features</h3><p>When I first started building apps with React Native, I focused on animations, performance, and pixel-perfect UI.<br>One day, while testing a application I build, a colleague turned on <strong>VoiceOver</strong> (on iOS) — and the screen reader didn’t read anything :) Buttons were just “unlabeled elements,” and inputs were “text field…”</p><p>That moment I think about development. I realized that accessibility (<strong>a11y</strong>) isn’t just about compliance — it’s about <strong>respect</strong>.<br>Respect for users who experience apps differently, yet deserve the same ease of use.</p><p>We need accessibility some form of disability person. Making your app accessible opens it up to more users.</p><p>Accessible features like high contrast, larger fonts, or voice navigation help <em>all</em> users.</p><p>So in this post, I’ll walk you through <strong>practical accessibility strategies</strong> for React Native apps — with working code examples and a developer’s perspective.</p><h3>⚙️ Accessibility in React Native</h3><p>React Native provides a strong foundation for accessibility on <strong>both iOS and Android</strong>, offering tools that bridge native accessibility systems like <strong>VoiceOver (iOS)</strong> and <strong>TalkBack (Android)</strong>. These tools allow screen readers and assistive technologies to understand and interact with your app’s UI elements.</p><p>React Native have built-in support for properties such as</p><ul><li>accessible,</li><li>accessibilityLabel,</li><li>accessibilityRole,</li><li>accessibilityHint,</li><li>importantForAccessibility and so on.</li></ul><p>with these props developers can create inclusive experiences <strong>without reinventing the wheel</strong>.</p><h3>📉 Let’s take some example to briefly understand</h3><h4>⚙️ 1. Labels, Roles, and Hints — Giving Your UI a Voice</h4><p>H<strong>elp screen readers understand your UI</strong>. React Native provides accessible, accessibilityLabel, accessibilityRole, and accessibilityHint , below is the code snippet how to use</p><pre>&lt;TouchableOpacity<br>  accessible={true}<br>  accessibilityLabel=&quot;Submit order&quot;<br>  accessibilityHint=&quot;Double tap to confirm your purchase&quot;<br>  accessibilityRole=&quot;button&quot;<br>  onPress={handleSubmit}<br>&gt;<br>  &lt;Text&gt;Submit&lt;/Text&gt;<br>&lt;/TouchableOpacity&gt;</pre><p><strong>What this does:</strong></p><ul><li>Screen readers announce: <em>“Submit order, button. Double tap to confirm your purchase.”</em></li></ul><p>Note — We have much more support from React native for more properties refer this <a href="https://reactnative.dev/docs/accessibility">Accessibility — React Native Documentation</a></p><h4>⚙️ 2. Accessibility in Forms</h4><p>Forms are where accessibility is often neglected — but easy to fix.</p><pre>&lt;View&gt;<br>  &lt;Text accessibilityRole=&quot;header&quot;&gt;Login&lt;/Text&gt;<br><br>  &lt;TextInput<br>    placeholder=&quot;Email&quot;<br>    accessibilityLabel=&quot;Email address&quot;<br>    keyboardType=&quot;email-address&quot;<br>  /&gt;<br><br>  &lt;TextInput<br>    placeholder=&quot;Password&quot;<br>    accessibilityLabel=&quot;Password field&quot;<br>    secureTextEntry<br>  /&gt;<br><br>  &lt;TouchableOpacity<br>    accessibilityLabel=&quot;Login button&quot;<br>    accessibilityHint=&quot;Logs you into the app&quot;<br>    onPress={handleLogin}<br>  &gt;<br>    &lt;Text&gt;Login&lt;/Text&gt;<br>  &lt;/TouchableOpacity&gt;<br>&lt;/View&gt;</pre><p><strong>What this does:</strong></p><ul><li>Screen readers announce: <em>“Email address, text field… Password field… Login button — logs you into the app.”</em></li></ul><h4>⚙️ 3. Support Dynamic Font Scaling</h4><p>Some users increase font sizes for better visibility. If your app ignores this, it breaks readability. React Native makes it easy to support system-wide font scaling.</p><pre>&lt;Text allowFontScaling={true}&gt;<br>  Welcome back, John!<br>&lt;/Text&gt;</pre><p>Note — If you’re using custom scaling libraries (like react-native-size-matters), ensure they respect system preferences.</p><p>Tip — Test by changing system font size under <strong>Settings → Accessibility → Display → Font Size</strong>.</p><h4>⚙️ 4. Ensure High Contrast &amp; Dark Mode Compatibility</h4><p>Color contrast is crucial — poor contrast can make text unreadable for users with low vision. React Native’s useColorScheme() hook helps you handle this gracefully.</p><pre>import { useColorScheme, Text } from &#39;react-native&#39;;<br><br>const colorScheme = useColorScheme();<br>const textColor = colorScheme === &#39;dark&#39; ? &#39;#fff&#39; : &#39;#000&#39;;</pre><p><strong>What this does:</strong></p><ul><li>The <strong>useColorScheme()</strong> hook in React Native <strong>subscribes to the system’s color scheme (light or dark mode)</strong> and updates <strong>in real time</strong> whenever the user changes the device appearance setting.</li></ul><h4>⚙️ 5. Control Focus Order and Navigation</h4><p>Screen readers navigate through focusable elements. If your screen has modals or custom components, you must guide focus manually.</p><pre>import { AccessibilityInfo, findNodeHandle, useRef } from &#39;react-native&#39;;<br><br>const SuccessModal = () =&gt; {<br>  const titleRef = useRef(null);<br><br>  useEffect(() =&gt; {<br>    const node = findNodeHandle(titleRef.current);<br>    if (node) AccessibilityInfo.setAccessibilityFocus(node);<br>  }, []);<br><br>  return (<br>    &lt;View accessible={true}&gt;<br>      &lt;Text ref={titleRef} accessibilityRole=&quot;header&quot;&gt;<br>        Payment Successful<br>      &lt;/Text&gt;<br>      &lt;Text&gt;Your order will be delivered soon.&lt;/Text&gt;<br>    &lt;/View&gt;<br>  );<br>};</pre><p><strong>What this does:</strong></p><ul><li>When the modal opens, the screen reader immediately focuses on <em>“Payment Successful”</em>, helping users orient themselves.</li></ul><h4>⚙️ 6. Large touch targets</h4><p>Users with motor disabilities, or even those using your app while walking, need tappable elements that are big enough and spaced apart properly.<br>According to <strong>WCAG (Web Content Accessibility Guidelines)</strong> and <strong>Apple’s Human Interface Guidelines</strong>, 👉 the minimum recommended <strong>touch target size</strong> is <strong>44×44 dp</strong>.</p><pre>&lt;TouchableOpacity<br>  onPress={handleLike}<br>  accessibilityLabel=&quot;Like this post&quot;<br>  accessibilityRole=&quot;button&quot;<br>  hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}<br>&gt;<br>  &lt;Image source={require(&#39;./heart.png&#39;)} style={{ width: 24, height: 24 }} /&gt;<br>&lt;/TouchableOpacity&gt;</pre><p><strong>What this does:</strong></p><ul><li>Increase tappable area of application without Changing Visual Size.</li></ul><h4>⚙️ 7. Haptic Feedback (Vibration)</h4><p>Some users can’t rely on <strong>visual</strong> or <strong>audio</strong> feedback alone — they may not see a toast message or hear a click sound. Adding <strong>haptic feedback</strong> gives them an <em>immediate tactile signal</em> that an action was successful (or failed).</p><pre>const handleDelete = async () =&gt; {<br>  await Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error);<br>  alert(&#39;Item deleted!&#39;);<br>};</pre><p><strong>What this does:</strong></p><ul><li>This triggers a <strong>sharper vibration</strong>, letting users instantly sense that something important happened.</li></ul><h3>🧪 How to Test &amp; Validate Accessibility in React Native</h3><p>Let’s look at the best ways to test accessibility in React Native apps 👇</p><h4>1. Manual Testing with Screen Readers</h4><p>The first and most important step is <strong>hands-on testing</strong> using native accessibility tools.</p><ul><li><strong>iOS:</strong> Use <strong>VoiceOver</strong> (enable from <em>Settings → Accessibility → VoiceOver</em>).</li><li><strong>Android:</strong> Use <strong>TalkBack</strong> (enable from <em>Settings → Accessibility → TalkBack</em>).</li></ul><h3>2. Automated Testing Tools</h3><p>A few third-party and native tools can help automate accessibility checks:</p><ul><li><strong>@react-native-community/eslint-plugin-a11y</strong> — integrates with ESLint to catch common accessibility issues.</li><li><strong>Detox + Jest</strong> — can be combined for automated accessibility validation in UI tests.</li><li><strong>Google Accessibility Scanner (Android)</strong> — scans your app for a11y issues like low contrast or missing labels.</li><li><strong>Xcode Accessibility Inspector (iOS)</strong> — visualizes accessibility hierarchy and properties.</li></ul><p>Accessibility testing is not a one-time process — it’s an <strong>ongoing part of your development workflow</strong>. Every new feature, update, or redesign should include accessibility validation.<br>By regularly testing, you ensure your app stays inclusive, usable, and delightful for <strong>everyone</strong>.</p><h3>📝 Short Note</h3><p>These are some of the most common <strong>accessibility (a11y) features</strong> every React Native developer should consider while building applications. You may not need to use all of them at once, but applying the right <strong>combination of these properties and techniques</strong> ensures that your app is truly <strong>inclusive and user-friendly for everyone</strong>.</p><p>Making accessibility a part of your development process isn’t just a checklist — it’s a commitment to creating apps that <strong>welcome every user</strong>, regardless of ability or environment.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aaab1fad4228" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/make-your-app-inclusive-accessibility-strategies-that-every-react-native-developer-should-know-aaab1fad4228">🧩 Make Your App Inclusive: Accessibility Strategies That Every React Native Developer Should Know</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Hey LinkedIn Users, Let’s Make Your Posts Stand Out!]]></title>
            <link>https://medium.com/mighty-ghost-hack/hey-linkedin-users-lets-make-your-posts-stand-out-a7ff1f0ce080?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/a7ff1f0ce080</guid>
            <category><![CDATA[linkedin-post-generator]]></category>
            <category><![CDATA[linkedin-marketing]]></category>
            <category><![CDATA[chrome-extension]]></category>
            <category><![CDATA[linkedin]]></category>
            <category><![CDATA[linkedin-post-engagement]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Sun, 02 Feb 2025 09:47:03 GMT</pubDate>
            <atom:updated>2025-02-02T09:49:59.770Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kiIeSRBhoAZYnTHVhcV5Wg.png" /></figure><p>Ever felt frustrated that <strong>LinkedIn doesn’t support bold, italic, or underlined text</strong>? 🤯</p><p>I did too! So, I built something cool — <strong>LinkedIn Text Formatter</strong> 🎉</p><h3>🔥 What’s the problem?</h3><p>LinkedIn keeps things plain — <strong>no HTML tags, no markdown, no built-in formatting options</strong>. That means:<br>❌ No way to highlight key points<br>❌ No easy way to structure your thoughts<br>❌ No way to add a bit of personality to your posts</p><p>Meanwhile, platforms like <strong>LeetCode, Discord, and Twitter</strong> allow formatted text using Unicode. So I thought — <em>why not bring that same magic to LinkedIn?</em></p><h3>💡 The Solution: A Simple, Free Chrome Extension</h3><p>With <strong>LinkedIn Text Formatter</strong>, you can now effortlessly format your posts with:<br>✅ <strong>𝐁𝐨𝐥𝐝, 𝑰𝒕𝒂𝒍𝒊𝒄, U̲n̲d̲e̲r̲l̲i̲n̲e̲, and </strong>• <strong>Bullet etc</strong><br>✅ <strong>Live Preview of typed text</strong>🔥<br>✅ <strong>Instant Copy-Paste for LinkedIn</strong><br>✅ <strong>Emoji Support 😃🎉</strong><br>✅ <strong>100% Free &amp; Open Source</strong></p><h3>⚡ How It Works</h3><p>It’s super simple:<br>1️⃣ Type your text into the <strong>formatter</strong><br>2️⃣ Watch the <strong>Live Preview</strong> update in real time<br>3️⃣ Click <strong>Copy</strong> and paste it directly into LinkedIn</p><p>That’s it! 🎯</p><h3>💻 Open Source — Get Involved!</h3><p>This is an <strong>open-source project</strong>, and I’d love for you to explore the code, contribute, or suggest improvements. <strong>Let’s build and learn together! 🚀</strong></p><h3>🚀 Try It Out!</h3><p>🔹 <strong>Chrome Extension:</strong> <a href="https://chromewebstore.google.com/detail/linkedin-text-formatter/kmkpoekjjjnmhdpdcnfgmionlkadnold">Install Here</a><br>🔹 <strong>Live Web Version:</strong> <a href="https://mayurkadampro.github.io/LinkedIn-Text-Formatter/">Try Here</a><br>🔹 <strong>GitHub Repository:</strong> <a href="https://github.com/mayurkadampro/LinkedIn-Text-Formatter">Check the Code</a></p><h3>🤝 Your Feedback Matters!</h3><p>Would love to hear your thoughts! <strong>Try it out and drop your feedback</strong> — it’ll help shape future updates. Who knows? AI-powered suggestions or hashtag generators could be next! 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a7ff1f0ce080" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/hey-linkedin-users-lets-make-your-posts-stand-out-a7ff1f0ce080">Hey LinkedIn Users, Let’s Make Your Posts Stand Out!</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Interview Experience with FanCode for a React Native Developer Role]]></title>
            <link>https://medium.com/mighty-ghost-hack/interview-experience-with-fancode-for-a-react-native-developer-role-dca760fd781b?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/dca760fd781b</guid>
            <category><![CDATA[sde-interview]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[interivew]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[fancode]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Sat, 14 Dec 2024 10:25:53 GMT</pubDate>
            <atom:updated>2024-12-14T10:25:40.339Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NMeGgyf08a9MNrf5JwnQIQ.png" /></figure><p>Over the last few months, I’ve been preparing for React Native developer positions and recently had the opportunity to interview with FanCode. The process was intense, insightful, and filled with learning moments. I want to share my experience to help others prepare for similar roles.</p><h3>Interview Rounds</h3><p>1. Online Assessment (1 hr &amp; 15 mins)<br>2. Problem Solving (60 mins)<br>3. Platform Round (60 mins)<br>4. Design Round (60 mins)</p><p>Once you clear all rounds, there will be 2 more rounds of interviews with engineering leadership, mainly to test for cultural fitment.</p><h3>Round 1: Online Assessment</h3><p>This round included three different programming questions, and I was given 1 hour and 15 minutes to complete them. The questions I encountered were:</p><ol><li><strong>Limit Promise Concurrency:</strong> Implement a function that dynamically manages the concurrency limit while processing multiple promises.</li><li><strong>Remove Circular Dependency:</strong> Write a function to remove circular dependencies from a given object.</li><li><strong>Polyfill for </strong><strong>setAllTimeout and </strong><strong>clearAllTimeout:</strong> Implement a polyfill for both these functions.</li></ol><p>I was able to complete all three questions. However, for the second problem (removing circular dependencies), some test cases failed as I could not handle certain edge cases. Despite this, I scored enough to advance to the next round.</p><h3>Round 2: Problem Solving</h3><p>This round focused on testing JavaScript proficiency by requiring the implementation of three polyfills. Candidates had 60 minutes to write working, executable solutions for the provided tasks.</p><p>The questions I encountered were:</p><ol><li><strong>Flatten Array by Level:</strong> Write a polyfill to flatten an array to a specified depth. For example:</li></ol><pre>flatten([1, [2, [3, [4]]]], 2);<br>// Output: [1, 2, 3, [4]]</pre><ol><li><strong>SetInterval and ClearInterval:</strong> Implement polyfills for the setInterval and clearInterval methods, mimicking their behaviour using setTimeout.</li><li><strong>Promise.allSettled Method:</strong> Write a polyfill for Promise.allSettled, which takes an array of promises and returns a promise that resolves after all of the given promises have either been fulfilled or rejected.</li></ol><p>I completed all three questions within the allotted time and ensured the solutions were robust and executable. Clearing this round allowed me to progress to the <strong>Platform Round</strong>.</p><h3>Round 3: Platform Round</h3><p>This round primarily tested my in-depth knowledge of React Native architecture and its modern advancements. The 60-minute session was divided into three sections, each focusing on different aspects of React Native expertise.</p><p><strong>Section 1: React Native Architecture Discussion<br></strong>In this segment, the interviewer asked detailed questions about React Native’s architectural evolution. The topics included:</p><ul><li><strong>Old vs. New Architecture:</strong> Differences between the old architecture (based on the bridge) and the new one (TurboModules, JSI, and Fabric).</li><li><strong>Optimization Improvements:</strong> Discussed enhancements like reduced bridge bottlenecks, faster rendering via Fabric and the role of Hermes in improving performance.</li><li><strong>Why Updates Were Necessary:</strong> They probed into the reasons for adopting TurboModules and JSI, highlighting their impact on app performance and inter-module communication.</li><li><strong>How It Works Internally:</strong> Questions centred around how JSI facilitates direct communication with the JavaScript engine and eliminates the need for serialization/deserialization via the bridge.</li></ul><p>The pattern of questioning was consistent: <strong>“What is it? Why was it introduced? How does it work?”</strong> This required both theoretical knowledge and a practical understanding of React Native internals.</p><p><strong>Section 2: Native Component &amp; Module Implementation</strong><br>In this part, the interviewer provided documentation with the design for a native component and module that I had to implement. This required:</p><ul><li><strong>Creating a Native Component</strong> using Android’s SimpleViewManager.</li><li><strong>Developing a Native Module</strong> to handle custom business logic.</li></ul><p>I managed to complete about 80% of the implementation due to time constraints. The focus was on:</p><ul><li>Writing clean, reusable native code.</li><li>Ensuring seamless integration with React Native.</li></ul><p><strong>Section 3: React Fundamentals and Patterns<br></strong>The final section comprised verbal questions on core React and React Native concepts. Topics included:</p><ul><li><strong>React Component Lifecycle:</strong> How to React Native leverages lifecycle methods.</li><li><strong>State Management:</strong> Best practices for managing state in large applications.</li><li><strong>React Hooks:</strong> Practical usage of useEffect, useContext, and custom hooks.</li><li><strong>Design Patterns:</strong> Discussion on reusable component patterns and optimizing performance in React Native apps.</li></ul><p>Completing most of the coding tasks and demonstrating a solid understanding of React fundamentals helped me move forward to the next round.</p><h3>Round 4: Design Round</h3><p>This round tested my ability to design systems and applications effectively, with a focus on both backend and frontend aspects. The task provided by the interviewer was to design a <strong>Slack messaging system</strong> with the following requirements:</p><ol><li><strong>Peer-to-Peer Messaging:</strong> Enable real-time, direct communication between two users.</li><li><strong>Group Messaging:</strong> Support for creating and managing group conversations.</li><li><strong>API Design:</strong> Design RESTful APIs that handle messaging functionality efficiently.</li><li><strong>History: </strong>Store chat history of conversation.</li></ol><h4>Functional and Non-Functional Requirements</h4><p>The interviewer expected a detailed breakdown of both <strong>functional</strong> (e.g., sending, and receiving messages) and <strong>non-functional</strong> requirements (e.g., performance, scalability, data consistency). They emphasized maintaining <strong>real-time communication</strong> and ensuring <strong>scalable backend architecture</strong>.</p><h4>My Approach</h4><p><strong>Backend Design — </strong>Proposed a distributed system architecture using WebSockets for real-time communication.</p><p><strong>API Design — </strong>Created a plan for APIs, including endpoints for sending, receiving, fetching old messages, and managing groups &amp; focused on ensuring low latency for real-time events while keeping APIs stateless for ease of maintenance.</p><p><strong>Frontend Design Discussion</strong><br>After completing the system design, the discussion shifted toward the frontend. The interviewer asked how I would efficiently display and paginate messages given the API responses. Key points included:</p><ul><li><strong>Data Fetching and Caching:</strong> Use infinite scrolling for message lists with APIs returning batched data.</li><li><strong>State Management:</strong> Manage the state effectively using a combination of Redux and React Query for real-time updates.</li><li><strong>Unread Message Count: </strong>Display the user&#39;s unread message optimally count over UI.</li></ul><p>Although I was able to answer most of the questions, a couple of edge cases stumped me, particularly around <strong>questions related to WebSockets &amp; its response</strong>.</p><h3>Outcome</h3><p>After a week of anxious waiting, I received an email from FanCode stating that they would not be moving forward with my application. The message read:</p><p><em>“After much discussion and analysis with the team, we, unfortunately, have decided not to proceed with signing you on at this time. However, we will keep your profile on file, and as soon as a position aligns with your talent, we will reach out!”</em></p><p>While I didn’t make it to the finish line, I gained practical knowledge and feel motivated to keep growing as a developer. Looking forward to the next adventure!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dca760fd781b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/interview-experience-with-fancode-for-a-react-native-developer-role-dca760fd781b">Interview Experience with FanCode for a React Native Developer Role</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Build a Word Search Game to visualize a Depth-First Search Algorithm]]></title>
            <link>https://medium.com/mighty-ghost-hack/build-a-word-search-game-to-visualize-a-depth-first-search-algorithm-1c6bc58d2583?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/1c6bc58d2583</guid>
            <category><![CDATA[word-search]]></category>
            <category><![CDATA[data-structure-algorithm]]></category>
            <category><![CDATA[data-structures]]></category>
            <category><![CDATA[code]]></category>
            <category><![CDATA[dfs]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Mon, 11 Nov 2024 12:38:10 GMT</pubDate>
            <atom:updated>2024-11-11T12:37:58.664Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AI-pjoCwXCUXKOsrMWIFmA.png" /></figure><p>Are you curious about how Depth-First Search (DFS) works? This Word Search Game is an interactive tool designed specifically for learners interested in understanding data structures, particularly through visualizing DFS in action.</p><p><strong>Note:</strong> This isn’t a traditional game where users manually select a matching grid, search for words and receive feedback on correctness. Instead, it’s a visual tool designed to demonstrate how the DFS algorithm operates to find words automatically within a grid.</p><h3>Project Overview</h3><p>In this project, we’ll build a user interface that includes:</p><ul><li><strong>Two input fields</strong>: One for selecting a target word and another for user input.</li><li><strong>Customization options</strong>: Controls to adjust the grid size and the speed of the DFS search.</li><li><strong>Visual controls</strong>: Buttons to start the search, shuffle the grid, and reset the game.</li><li><strong>Responsive UI</strong>: Designed for both mobile and desktop views.</li></ul><h3>Core Algorithms</h3><ol><li><strong>Depth-First Search (DFS)</strong>: Used for pattern matching and locating word sequences in the grid.</li><li><strong>Linear Search</strong>: Extracts valid words from the grid for visualization purposes.</li></ol><p>The main focus of this article will be on the algorithmic backbone of the project: implementing DFS and linear search. For UI components, feel free to use any front-end framework of your choice, such as React, Vue, or Angular.</p><h3>Why DFS for Word Search?</h3><p>DFS is known for exploring all possible paths from a given node before moving on to the next. This makes it ideal for problems.</p><p>DFS provides the functionality to thoroughly explore every possible letter combination in a word search grid, making it possible to find valid words without missing any options.</p><p>In this project, we’ll explore DFS in a 2D grid (the word search board) where each cell is a node connected to its adjacent cells. We aim to demonstrate how DFS can systematically search for words by exploring all possible paths within the grid.</p><h3>Understanding the DFS for Word Search</h3><p>DFS works by exploring each path fully before backtracking. Here’s a basic pseudocode for DFS in a grid context:</p><ol><li>Start at a cell and mark it as visited.</li><li>Recursively explore each unvisited neighbouring cell.</li><li>If a cell matches the next character in the target word, continue the search.</li><li>If all characters are found, the word is located.</li><li>Backtrack if a path doesn’t match the word.</li></ol><p>In this project, DFS will dynamically navigate through grid cells to check if the word exists in different directions.</p><p>For simplicity, I have only included horizontal and vertical directions. However, real word search puzzles also look for diagonal paths, which can be easily implemented. I will add this feature if there is positive feedback on this project. Since this open-source project is available on GitHub, I encourage learners to fork the repository and add more features as they wish.</p><h3>Implementing the DFS Algorithm in JavaScript</h3><pre>var dfsSearch = function (board, word) {<br>    let result = false;<br><br>    var validate = (row, col, k) =&gt; {<br><br>        // Out of boundary case for recursive call<br>        if (row &lt; 0 || col &lt; 0 || row &gt;= board.length || col &gt;= board[0].length) return;<br><br>        // Wrong Character<br>        if (board[row][col] != word[k]) return false;<br><br>        // Base case to return from recursive call<br>        if (k === word.length - 1) {<br>            result = true;<br>            return true;<br>        }<br><br>        // Change value as null so we dont go back and forth<br>        board[row][col] = null;<br><br>        // try all directions<br>        validate(row + 1, col, k + 1);<br>        validate(row - 1, col, k + 1);<br>        validate(row, col + 1, k + 1);<br>        validate(row, col - 1, k + 1);<br><br>        // Change into real value, reset the board.<br>        board[row][col] = word[k];<br>    }<br><br>    // Iterative loop<br>    for (let i = 0; i &lt; board.length; i++) {<br>        for (let j = 0; j &lt; board[0].length; j++) {<br>            if (board[i][j] === word[0]) {<br>                if (validate(i, j, 0)) return true;<br>            }<br>        }<br>    }<br><br>    return result;<br>};</pre><p>A similar leetcode problem is available (<a href="https://leetcode.com/problems/word-search/">Problem #79</a>). I recommend first solving the Word Search problem on LeetCode. This problem will help you grasp the core concepts.</p><h3>Implementation of Extract text in JavaScript</h3><p>We can extract potential words from the grid using linear search to find sequences in different directions. Here’s a basic JavaScript function for extracting words:</p><pre>const extractWordsFromGrid = (grid, minLength = 3) =&gt; {<br>  const words = new Set();<br><br>  const numRows = grid.length;<br>  const numCols = grid[0].length;<br><br>  const addWord = (word) =&gt; {<br>    <br>    if (word.length &gt;= minLength) {<br>      words.add(word);<br>    }<br>  };<br><br>  // Extract horizontal words<br>  for (let row = 0; row &lt; numRows; row++) {<br>    let rowStr = grid[row].slice(0, randomIntFromInterval(1, grid[row].length - 1)).join(&quot;&quot;);<br>    addWord(rowStr); // Left-to-right<br>    addWord([...rowStr].reverse().join(&quot;&quot;)); // Right-to-left<br>  }<br><br>  // Extract vertical words<br>  for (let col = 0; col &lt; numCols; col++) {<br>    let colStr = [];<br>    for (let row = 0; row &lt; numRows; row++) {<br>      colStr.push(grid[row][col]);<br>      <br>    }<br>    <br>    addWord(colStr.slice(0, randomIntFromInterval(1, colStr.length - 1)).join(&quot;&quot;)); // Top-to-bottom<br>    addWord([...colStr].reverse().join(&quot;&quot;)); // Bottom-to-top<br>  }<br>  <br>  return shuffleElements(Array.from(words)); // Convert Set to Array for output<br>};<br><br>const randomIntFromInterval = (min, max) =&gt; {<br>  return Math.floor(Math.random() * (max - min + 1) + min);<br>};<br><br>const shuffleElements = (arr) =&gt; {<br>  return arr.sort((a, b) =&gt; Math.random() - 0.5);<br>};</pre><h3>DFS Traversal Visualization</h3><p>To enhance the user experience, we use a colour scheme to visualize the DFS traversal:</p><ul><li><strong>Green</strong>: Indicates cells that match the word.</li><li><strong>Yellow</strong>: Shows DFS traversal as it moves through each cell.</li><li><strong>Sky Blue</strong>: Highlights the next potential match.</li></ul><p>Each cell changes colour to reflect the DFS progression, and a delay is applied between steps (adjustable via a speed control slider) to allow users to follow the search process in real-time.</p><h3>Project Resources</h3><p>The complete code for this project is available on <a href="https://github.com/mayurkadampro/Word-Search-DFS-Visualization">GitHub</a>, allowing you to explore the full implementation or contribute by adding more features.</p><p><strong>Play with the Game</strong>: Experience the Word Search DFS Visualization through the interactive link — <a href="https://mayurkadampro.github.io/Word-Search-DFS-Visualization/">https://mayurkadampro.github.io/Word-Search-DFS-Visualization/</a></p><p><strong>GitHub Repository</strong>: Check out the entire codebase and feel free to fork the repo to add additional features — <a href="https://github.com/mayurkadampro/Word-Search-DFS-Visualization">https://github.com/mayurkadampro/Word-Search-DFS-Visualization</a></p><p>If you enjoyed this article and found the visualization tool helpful for understanding how DFS works with grid-based structures, please consider following me for more practical projects and hands-on tutorials. Stay tuned for exciting new content on data structures, algorithms, and interactive learning tools!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1c6bc58d2583" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/build-a-word-search-game-to-visualize-a-depth-first-search-algorithm-1c6bc58d2583">Build a Word Search Game to visualize a Depth-First Search Algorithm</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Simple Circuit Breaker in JavaScript to Handle Repeated Failures]]></title>
            <link>https://medium.com/mighty-ghost-hack/building-a-simple-circuit-breaker-in-javascript-to-handle-repeated-failures-9c063e50b8f5?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/9c063e50b8f5</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[design-patterns]]></category>
            <category><![CDATA[circuit-breaker]]></category>
            <category><![CDATA[javascript-development]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Fri, 08 Nov 2024 12:07:54 GMT</pubDate>
            <atom:updated>2024-11-08T12:07:16.115Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EeQwftj00jlvecEBDPrgyw.png" /></figure><p>Developing applications that rely on external APIs or services, a common challenge is handling repeated failures gracefully. Imagine a scenario where an API becomes temporarily unavailable — calling it over and over will only increase the load and waste resources. To address this, we can implement a <strong>circuit breaker pattern</strong>.</p><p>This pattern stops calls to the failing service temporarily and resumes them after a set time, allowing the service to recover. In this post, we’ll build a simple JavaScript circuitBreaker function to illustrate this concept.</p><h3>Why Use a Circuit Breaker?</h3><p>A circuit breaker prevents your system from getting overwhelmed by failing calls. Here are the main reasons to use it:</p><ol><li><strong>Reduces unnecessary load</strong>: Stops repeated, futile calls to a failing service.</li><li><strong>Allows recovery time</strong>: Gives the failing service time to get back up.</li><li><strong>Improves user experience</strong>: Avoids showing repeated error messages to the user.</li></ol><h3>We’ll create a circuitBreaker function that:</h3><ul><li>Attempts to call a function (like an API request).</li><li>Counts consecutive failures.</li><li>Temporarily halts further calls after a fixed number of failures (threshold).</li><li>Resume calls after a specified period (halt time).</li></ul><pre>const HALT_TIME = 5000; // 5 seconds<br>const FAILED_THRESHOLD = 3; // Number of failed attempts before halting<br><br>const circuitBreaker = (cb, haltTime = HALT_TIME, failThreshold = FAILED_THRESHOLD) =&gt; {<br>    let failCount = 0;<br>    let isHalted = false;<br>    let timeout;<br><br>    return () =&gt; {<br>        if (isHalted) {<br>            console.log(&quot;Service is currently unavailable. Please wait a moment and try again.&quot;);<br>            return;<br>        }<br><br>        try {<br>            const result = cb();<br>            failCount = 0; // Reset fail count if call succeeds<br>            console.log(&quot;Call succeeded&quot;);<br>            return result;<br>        } catch (error) {<br>            failCount++;<br>            console.log(`Call failed (${failCount}/${failThreshold})`);<br><br>            if (failCount &gt;= failThreshold) {<br>                isHalted = true;<br>                console.log(`Threshold reached. Halting calls for ${haltTime / 1000} seconds.`);<br><br>                timeout = setTimeout(() =&gt; {<br>                    failCount = 0; // Reset fail count after halt period<br>                    isHalted = false;<br>                    console.log(&quot;Service resumed.&quot;);<br>                }, haltTime);<br>            }<br>        }<br>    };<br>};<br><br>// Example usage:<br>const mockApiCall = () =&gt; {<br>    if (Math.random() &gt; 0.5) {<br>        throw new Error(&quot;API call failed.&quot;);<br>    }<br>    return &quot;API call succeeded.&quot;;<br>};<br><br>const testFunction = circuitBreaker(mockApiCall);<br><br>// Simulate multiple calls<br>for (let i = 0; i &lt; 10; i++) {<br>    testFunction();<br>}<br><br><br>// let request after some interval<br>setTimeout(() =&gt; {<br>    testFunction();<br>}, HALT_TIME);</pre><h3>Output</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QgjrGCWjic2F0jJDGa9UHA.png" /></figure><h3>Explanation of Key Parts</h3><p><strong>Configuration Variables</strong>:</p><ul><li>HALT_TIME sets how long to halt calls after too many failures.</li><li>FAILED_THRESHOLD sets the number of consecutive failures allowed before halting.</li></ul><p><strong>Circuit Breaker Logic</strong>:</p><ul><li>failCount keeps track of consecutive failures.</li><li>isHalted is a flag that prevents further calls when set to true.</li></ul><p><strong>Function Return and Timeout</strong>:</p><ul><li>If the function succeeds, failCount resets.</li><li>When failCount reaches the threshold, a timeout is set to halt further calls temporarily.</li><li>After haltTime, the timeout resets failCount and clears isHalted, allowing calls to resume.</li></ul><h3>Conclusion</h3><p>With this circuitBreaker function, you can control how your JavaScript code handles repeated failures, making your application more robust and reliable. This pattern is especially useful in microservices and cloud environments where services may temporarily experience load issues or maintenance downtime. You can also extend this circuit breaker to log failures, alert users, or dynamically adjust the halt time based on usage patterns.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9c063e50b8f5" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/building-a-simple-circuit-breaker-in-javascript-to-handle-repeated-failures-9c063e50b8f5">Building a Simple Circuit Breaker in JavaScript to Handle Repeated Failures</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[In-Person Interview Experience at Dream11 [SDE-2] | Mumbai]]></title>
            <link>https://medium.com/mighty-ghost-hack/in-person-interview-experience-at-dream11-sde-2-mumbai-a47f1e415673?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/a47f1e415673</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[dream11-interview]]></category>
            <category><![CDATA[platform-round]]></category>
            <category><![CDATA[sde2]]></category>
            <category><![CDATA[dream11]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Mon, 28 Oct 2024 07:10:53 GMT</pubDate>
            <atom:updated>2024-10-28T07:05:52.185Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/910/1*EYtf4O4eSl3uT1oObOCGUw.jpeg" /></figure><p>Interviewing for the SDE-2 position at Dream11 was both challenging and insightful. Although I wasn’t selected, I walked away with new insights and a better understanding of the interview process at a top tech company. Here’s a breakdown of the experience, my challenges, and the valuable lessons I learned.</p><h3>Initial Contact</h3><p>The process started with a phone call from a Dream11 recruiter. The initial phone screening was straightforward, focusing on my background and experience to assess whether my profile was a good match. Once cleared, I was invited to the next stage—a virtual DSA (Data Structures and Algorithms) coding round.</p><h3>Round 1: Virtual DSA Coding Challenge</h3><p><strong>Date:</strong> October 18, 2024<br><strong>Format:</strong> Virtual<br><strong>Duration</strong>: 1hr<br><strong>Interview Panel</strong>: SDE3 at Dream11</p><blockquote><a href="https://leetcode.com/problems/search-in-rotated-sorted-array/"><em>Search in Rotated Sorted Array</em></a></blockquote><blockquote><a href="https://leetcode.com/problems/missing-number/"><em>Missing Number</em></a></blockquote><blockquote><a href="https://leetcode.com/problems/longest-substring-without-repeating-characters"><em>Longest Substring</em></a></blockquote><p>I had to solve three DSA problems. This round evaluated problem-solving speed and accuracy. I was able to clear this round, which felt like a small victory and a boost of confidence to tackle what lay ahead.</p><h3>Round 2: The In-Office Platform Round</h3><p>The next step was an on-site interview at Dream11’s Mumbai office. This “Platform Round” was more intense, involving a 40-minute coding session split between two problems. Here’s how it went:</p><blockquote><strong>Problem 1</strong>: CSV to JSON with the optimal solution</blockquote><blockquote>I attempted a complex approach, but time constraints made it challenging to implement fully.</blockquote><blockquote>however for your refrence you can find below optimize solution.</blockquote><blockquote>Solution — <a href="https://github.com/mayurkadampro/JavaScript-Coding-Interview-Problems/blob/main/Interview%20Question/CSVToJSON.js">https://github.com/mayurkadampro/JavaScript-Coding-Interview-Problems/blob/main/Interview%20Question/CSVToJSON.js</a></blockquote><blockquote><strong>Problem 2</strong>: implementation of a rate limiter that evenly distributes requests over a one-minute period using JavaScript closures</blockquote><blockquote>I solved it partially within the 20-minute limit.</blockquote><blockquote>Solution — <a href="https://github.com/mayurkadampro/JavaScript-Coding-Interview-Problems/blob/main/Interview%20Question/rateLimiter.js">https://github.com/mayurkadampro/JavaScript-Coding-Interview-Problems/blob/main/Interview%20Question/rateLimiter.js</a></blockquote><p>While I couldn’t complete the round to my satisfaction, I learned the importance of quick decision-making under pressure and the value of opting for simpler approaches where possible.</p><p>This round was heavily focused on coding knowledge and algorithmic skills, highlighting the standards Dream11 sets for its engineering team.</p><h3>What I Learned</h3><p>Although I didn’t advance further, I took away valuable lessons to apply to future interviews:</p><ul><li><strong>Time Management</strong>: Breaking down the problem and choosing the most efficient solution in a limited time is key.</li><li><strong>Complexity Awareness</strong>: Sometimes, the simplest approach is the best approach, especially when the clock is ticking.</li><li><strong>Resilience</strong>: Every round brings new insights that make you stronger for the next opportunity.</li></ul><h3>Takeaway</h3><p>Each interview is a stepping stone toward growth. While I wasn’t selected this time, the experience helped me refine my problem-solving approach and reinforced my dedication to continuous learning.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a47f1e415673" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/in-person-interview-experience-at-dream11-sde-2-mumbai-a47f1e415673">In-Person Interview Experience at Dream11 [SDE-2] | Mumbai</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Javascript DOM Manipulation methods]]></title>
            <link>https://medium.com/mighty-ghost-hack/javascript-dom-manipulation-methods-797a015c282f?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/797a015c282f</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[javascript-development]]></category>
            <category><![CDATA[dom]]></category>
            <category><![CDATA[javascript-dom]]></category>
            <category><![CDATA[javascript-dom-tips]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Fri, 25 Oct 2024 16:13:40 GMT</pubDate>
            <atom:updated>2024-10-25T16:16:15.511Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/762/1*l2JdXv72oRNe6FifhgZG6g.png" /><figcaption><em>A graphical representation of the HTML DOM tree</em></figcaption></figure><h3>What is the DOM?</h3><p>DOM stands for Document Object Model.</p><p>The <strong>Document</strong> part refers to the webpage you see in the browser—specifically, the HTML Document.</p><p><strong>Object</strong> means the elements like images, headers, and paragraphs are treated like objects. Each object has its properties (like id, class, style) and methods. Using these properties and methods, you can manipulate the elements.</p><p>The <strong>Model</strong> in DOM is a representation of the HTML document as a hierarchical tree. This tree includes all the elements. And it captures the parent-child relationships between them.</p><h3>DOM Manipulation</h3><ol><li>Selecting Elements</li><li>Creating Elements</li><li>Adding or Inserting Elements</li><li>Removing Elements</li><li>Modifying Element Content</li><li>Modifying Attributes</li><li>Modifying Styles</li><li>Traversing the DOM</li><li>Event Handling</li><li>Other Useful DOM Utility Methods</li></ol><h3>1. Selecting Elements</h3><p><strong>These methods allow you to select elements from the DOM:</strong></p><p><strong>document.getElementById(id)</strong>: Select an element by its id.</p><pre>const element = document.getElementById(&#39;myId&#39;);</pre><p><strong>document.getElementsByClassName(className)</strong>: Select all elements with the specified class.</p><pre>const elements = document.getElementsByClassName(&#39;myClass&#39;);</pre><p><strong>document.getElementsByTagName(tagName)</strong>: Selects all elements with the specified tag name.</p><pre>const elements = document.getElementsByTagName(&#39;div&#39;);</pre><p><strong>document.querySelector(selector)</strong>: Select the first element that matches a CSS selector.</p><pre>const element = document.querySelector(&#39;.myClass&#39;);</pre><p><strong>document.querySelectorAll(selector)</strong>: Select all elements that match a CSS selector.</p><pre>const elements = document.querySelectorAll(&#39;.myClass&#39;);</pre><h3>2. Creating Elements</h3><p><strong>These methods create new elements or text nodes:</strong></p><p><strong>document.createElement(tagName)</strong>: Creates a new element with the specified tag name.</p><pre>const newDiv = document.createElement(&#39;div&#39;);</pre><p><strong>document.createTextNode(text)</strong>: Creates a new text node with the specified text.</p><pre>const textNode = document.createTextNode(&#39;Hello World&#39;);</pre><h3>3. Adding or Inserting Elements</h3><p><strong>These methods add new elements to the DOM or insert elements at specific positions:</strong></p><p><strong>parentNode.appendChild(childNode)</strong>: Adds childNode as the last child of parentNode.</p><pre>document.body.appendChild(newDiv);</pre><p><strong>parentNode.insertBefore(newNode, referenceNode)</strong>: Inserts newNode before referenceNode within parentNode.</p><pre>const referenceNode = document.getElementById(&#39;myId&#39;);<br>document.body.insertBefore(newDiv, referenceNode);</pre><p><strong>parentNode.prepend(newNode)</strong>: Inserts newNode as the first child of parentNode.</p><pre>document.body.prepend(newDiv);</pre><p><strong>element.insertAdjacentElement(position, newElement)</strong>: Inserts an element relative to another element. Positions include beforebegin, afterbegin, beforeend, and afterend.</p><pre>element.insertAdjacentElement(&#39;beforeend&#39;, newDiv);</pre><h3>4. Removing Elements</h3><p>These methods remove elements or child nodes:</p><p><strong>parentNode.removeChild(childNode)</strong>: Removes childNode from parentNode.</p><pre>document.body.removeChild(newDiv);</pre><p><strong>element.remove()</strong>: Removes element from the DOM directly.</p><pre>newDiv.remove();</pre><h3>5. Modifying Element Content</h3><p><strong>These properties and methods modify the content inside elements:</strong></p><p><strong>element.textContent</strong>: Gets or sets the text content of an element.</p><pre>element.textContent = &#39;Hello, World!&#39;;</pre><p><strong>element.innerHTML</strong>: Gets or sets the HTML content of an element.</p><pre>element.innerHTML = &#39;&lt;strong&gt;Hello, World!&lt;/strong&gt;&#39;;</pre><p><strong>element.outerHTML</strong>: Gets or replaces the element itself with new HTML content.</p><pre>element.outerHTML = &#39;&lt;div&gt;New Content&lt;/div&gt;&#39;;</pre><h3>6. Modifying Attributes</h3><p><strong>These methods manage element attributes:</strong></p><p><strong>element.getAttribute(attributeName)</strong>: Gets the value of an attribute.</p><pre>const id = element.getAttribute(&#39;id&#39;);</pre><p><strong>element.setAttribute(attributeName, value)</strong>: Sets the value of an attribute.</p><pre>element.setAttribute(&#39;class&#39;, &#39;newClass&#39;);</pre><p><strong>element.removeAttribute(attributeName)</strong>: Removes an attribute.</p><pre>element.removeAttribute(&#39;class&#39;);</pre><p><strong>element.hasAttribute(attributeName)</strong>: Checks if an attribute exists.</p><pre>const hasId = element.hasAttribute(&#39;id&#39;);</pre><h3>7. Modifying Styles</h3><p><strong>These methods modify inline styles:</strong></p><p><strong>element.style.property</strong>: Sets an inline style property.</p><pre>element.style.color = &#39;red&#39;;</pre><p><strong>element.classList.add(className)</strong>: Adds a class to the element.</p><pre>element.classList.add(&#39;myClass&#39;);</pre><p><strong>element.classList.remove(className)</strong>: Removes a class from the element.</p><pre>element.classList.remove(&#39;myClass&#39;);</pre><p><strong>element.classList.toggle(className)</strong>: Toggles a class on or off.</p><pre>element.classList.toggle(&#39;active&#39;);</pre><p><strong>element.classList.contains(className)</strong>: Checks if an element contains a specified class.</p><pre>const hasClass = element.classList.contains(&#39;active&#39;);</pre><h3>8. Traversing the DOM</h3><p><strong>These properties and methods navigate through the DOM tree:</strong></p><p><strong>element.parentNode</strong>: Gets the parent of an element.</p><pre>const parent = element.parentNode;</pre><p><strong>element.childNodes</strong>: Gets a list of an element&#39;s child nodes.</p><pre>const children = element.childNodes;</pre><p><strong>element.firstChild</strong>: Gets the first child of an element.</p><pre>const firstChild = element.firstChild;</pre><p><strong>element.lastChild</strong>: Gets the last child of an element.</p><pre>const lastChild = element.lastChild;</pre><p><strong>element.previousSibling</strong>: Gets the previous sibling of an element.</p><pre>const prevSibling = element.previousSibling;</pre><p><strong>element.nextSibling</strong>: Gets the next sibling of an element.</p><pre>const nextSibling = element.nextSibling;</pre><p><strong>element.children</strong>: Returns an HTMLCollection of child elements.</p><pre>const childElements = element.children;</pre><p><strong>element.firstElementChild</strong> and <strong>element.lastElementChild</strong>: Access the first and last child elements.</p><pre>const firstElement = element.firstElementChild;</pre><h3>9. Event Handling</h3><p><strong>These methods attach and remove event listeners:</strong></p><p><strong>element.addEventListener(event, handler)</strong>: Attaches an event listener to an element.</p><pre>element.addEventListener(&#39;click&#39;, () =&gt; console.log(&#39;Clicked!&#39;));</pre><p><strong>element.removeEventListener(event, handler)</strong>: Removes an event listener from an element.</p><pre>element.removeEventListener(&#39;click&#39;, handler);<br>// OR<br>const listener = element.addEventListener(&#39;click&#39;, handler);<br>element.removeEventListener(listener);</pre><h3>10. Other Useful DOM Utility Methods</h3><p><strong>element.cloneNode(deep)</strong>: Creates a clone of an element. Pass true to also clone child elements.</p><pre>const clone = element.cloneNode(true);</pre><p><strong>element.contains(childNode)</strong>: Checks if an element contains a specific child node.</p><pre>const isContained = element.contains(childNode);</pre><p><strong>element.replaceChild(newChild, oldChild)</strong>: Replace an existing child with a new one.</p><pre>element.replaceChild(newNode, oldNode);</pre><p>These methods give you comprehensive control over the <strong>DOM</strong>, allowing you to select, create, manipulate, traverse, and delete elements dynamically, as well as handle events. This is essential for building interactive, dynamic web applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=797a015c282f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/javascript-dom-manipulation-methods-797a015c282f">Javascript DOM Manipulation methods</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SOLID Principles in React for Cleaner and Scalable Code]]></title>
            <link>https://medium.com/mighty-ghost-hack/solid-principles-in-react-for-cleaner-and-scalable-code-1695d12e79aa?source=rss----f5e9a2446544---4</link>
            <guid isPermaLink="false">https://medium.com/p/1695d12e79aa</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[solid]]></category>
            <category><![CDATA[solid-principles]]></category>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[react-native]]></category>
            <dc:creator><![CDATA[Mayur Kadam]]></dc:creator>
            <pubDate>Thu, 10 Oct 2024 14:46:38 GMT</pubDate>
            <atom:updated>2024-10-10T14:46:26.546Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0JoVEeTXY5wquT5y6jqrsA.png" /></figure><p>SOLID principles to React projects significantly enhance code quality, making it more maintainable, scalable, robust and flexible applications.</p><h3><strong>SOLID Principles in React</strong></h3><ol><li><strong>Single Responsibility Principle (SRP)</strong> — Focus on one task per component.</li><li><strong>Open/Closed Principle (OCP) </strong>— Extend components without modifying them.</li><li><strong>Liskov Substitution Principle (LSP)</strong> — Components should be interchangeable without breaking the application.</li><li><strong>Interface Segregation Principle (ISP) </strong>— Components should only take the necessary props, avoiding bloated interfaces.</li><li><strong>Dependency Inversion Principle (DIP) </strong>— Rely on abstractions (e.g., contexts, hooks) rather than concrete implementations for flexibility and decoupling.</li></ol><h3><strong>1. Single Responsibility Principle (SRP)</strong></h3><ul><li><strong>Definition</strong>: A component should have only one reason to change, meaning it should do one thing and do it well.</li><li><strong>In React</strong>: Break down large components into smaller, reusable pieces, each handling a single responsibility.</li></ul><p><strong>Not following SRP:</strong> In this example, the UserProfile component handles fetching data, managing state, and rendering the UI—all in one component.</p><pre>// ❌ BAD EXAMPLE - Violating SRP<br>import React, { useState, useEffect } from &#39;react&#39;;<br><br>const UserProfile = () =&gt; {<br>  const [user, setUser] = useState(null);<br>  const [loading, setLoading] = useState(true);<br>  const [error, setError] = useState(null);<br><br>  useEffect(() =&gt; {<br>    const fetchUserData = async () =&gt; {<br>      try {<br>        const response = await fetch(&#39;https://api.example.com/user&#39;);<br>        const data = await response.json();<br>        setUser(data);<br>      } catch (err) {<br>        setError(err);<br>      } finally {<br>        setLoading(false);<br>      }<br>    };<br>    fetchUserData();<br>  }, []);<br><br>  if (loading) return &lt;div&gt;Loading...&lt;/div&gt;;<br>  if (error) return &lt;div&gt;Error: {error.message}&lt;/div&gt;;<br><br>  return (<br>    &lt;div&gt;<br>      &lt;h2&gt;{user.name}&lt;/h2&gt;<br>      &lt;p&gt;{user.email}&lt;/p&gt;<br>    &lt;/div&gt;<br>  );<br>};<br><br>export default UserProfile;</pre><p><strong>Following SRP: </strong>Now, let’s refactor the code to adhere to the Single Responsibility Principle by breaking it into three separate components.</p><ol><li>Custom Hook for Data Fetching (useUserData)</li></ol><pre>// ✅ GOOD EXAMPLE - Following SRP<br>import { useState, useEffect } from &#39;react&#39;;<br><br>const useUserData = () =&gt; {<br>  const [user, setUser] = useState(null);<br>  const [loading, setLoading] = useState(true);<br>  const [error, setError] = useState(null);<br><br>  useEffect(() =&gt; {<br>    const fetchUserData = async () =&gt; {<br>      try {<br>        const response = await fetch(&#39;https://api.example.com/user&#39;);<br>        const data = await response.json();<br>        setUser(data);<br>      } catch (err) {<br>        setError(err);<br>      } finally {<br>        setLoading(false);<br>      }<br>    };<br>    fetchUserData();<br>  }, []);<br><br>  return { user, loading, error };<br>};<br><br>export default useUserData;</pre><p>2. Loading and Error Handling Component (UserInfo)</p><pre>// ✅ GOOD EXAMPLE - Following SRP<br>import React from &#39;react&#39;;<br><br>const UserInfo = ({ user, loading, error }) =&gt; {<br>  if (loading) return &lt;div&gt;Loading...&lt;/div&gt;;<br>  if (error) return &lt;div&gt;Error: {error.message}&lt;/div&gt;;<br><br>  return (<br>    &lt;div&gt;<br>      &lt;h2&gt;{user.name}&lt;/h2&gt;<br>      &lt;p&gt;{user.email}&lt;/p&gt;<br>    &lt;/div&gt;<br>  );<br>};<br><br>export default UserInfo;</pre><p>3. Main Component (UserProfile)</p><pre>// ✅ GOOD EXAMPLE - Following SRP<br>import React from &#39;react&#39;;<br>import useUserData from &#39;./useUserData&#39;;<br>import UserInfo from &#39;./UserInfo&#39;;<br><br>const UserProfile = () =&gt; {<br>  const { user, loading, error } = useUserData();<br><br>  return &lt;UserInfo user={user} loading={loading} error={error} /&gt;;<br>};<br><br>export default UserProfile;</pre><h3>2. Open/Closed Principle (OCP)</h3><ul><li><strong>Definition</strong>: Software entities should be open for extension but closed for modification.</li><li><strong>In React</strong>: Use higher-order components (HOCs), render props, or composition to extend component behaviour without modifying the existing code.</li></ul><p><strong>Not following OCP:</strong> In this example, the Button component has different styles based on the type prop. Every time a new button style is needed, we have to modify the existing Button component.</p><pre>// ❌ BAD EXAMPLE - Violating OCP<br>import React from &#39;react&#39;;<br><br>const Button = ({ type, label }) =&gt; {<br>  let style = {};<br><br>  if (type === &#39;primary&#39;) {<br>    style = { backgroundColor: &#39;blue&#39;, color: &#39;white&#39; };<br>  } else if (type === &#39;secondary&#39;) {<br>    style = { backgroundColor: &#39;gray&#39;, color: &#39;white&#39; };<br>  } else if (type === &#39;danger&#39;) {<br>    style = { backgroundColor: &#39;red&#39;, color: &#39;white&#39; };<br>  }<br><br>  return &lt;button style={style}&gt;{label}&lt;/button&gt;;<br>};<br><br>export default Button;</pre><p>Every time we want to add a new button type, we need to <strong>modify the existing component</strong> by adding a new if or else if conditions, which violates OCP.</p><p><strong>Following OCP: </strong>Instead of modifying the Button component for every new style, we can create a <strong>Higher-Order Component (HOC)</strong> that adds different styles based on the button type. This way, the Button component remains unchanged, and we can extend its behaviour by wrapping it with different HOCs.</p><pre>// ✅ GOOD EXAMPLE - Following OCP<br>import React from &#39;react&#39;;<br><br>// Base Button Component<br>const Button = ({ style, label }) =&gt; {<br>  return &lt;button style={style}&gt;{label}&lt;/button&gt;;<br>};<br><br>// HOC for Primary Button<br>const withPrimaryStyle = (WrappedComponent) =&gt; {<br>  return (props) =&gt; {<br>    const style = { backgroundColor: &#39;blue&#39;, color: &#39;white&#39; };<br>    return &lt;WrappedComponent {...props} style={style} /&gt;;<br>  };<br>};<br><br>// HOC for Secondary Button<br>const withSecondaryStyle = (WrappedComponent) =&gt; {<br>  return (props) =&gt; {<br>    const style = { backgroundColor: &#39;gray&#39;, color: &#39;white&#39; };<br>    return &lt;WrappedComponent {...props} style={style} /&gt;;<br>  };<br>};<br><br>// HOC for Danger Button<br>const withDangerStyle = (WrappedComponent) =&gt; {<br>  return (props) =&gt; {<br>    const style = { backgroundColor: &#39;red&#39;, color: &#39;white&#39; };<br>    return &lt;WrappedComponent {...props} style={style} /&gt;;<br>  };<br>};<br><br>// Use the HOCs<br>const PrimaryButton = withPrimaryStyle(Button);<br>const SecondaryButton = withSecondaryStyle(Button);<br>const DangerButton = withDangerStyle(Button);<br><br>const App = () =&gt; (<br>  &lt;div&gt;<br>    &lt;PrimaryButton label=&quot;Primary Button&quot; /&gt;<br>    &lt;SecondaryButton label=&quot;Secondary Button&quot; /&gt;<br>    &lt;DangerButton label=&quot;Danger Button&quot; /&gt;<br>  &lt;/div&gt;<br>);<br><br>export default App;</pre><h3>3. Liskov Substitution Principle (LSP)</h3><ul><li><strong>Definition</strong>: Objects or components should be replaceable with instances of their subtypes without altering the correctness of the program.</li><li><strong>In React</strong>: When creating components or extending them, ensure they can be used interchangeably without breaking the application.</li></ul><p><strong>Not following LSP:</strong> In this example, incorrect use of interface methods and not following the base interface for the same type of component violates the LSP principle.</p><pre>// ❌ BAD EXAMPLE - Violating LSP<br>interface BadBaseButton {<br>  onClick: () =&gt; void;<br>  text: string;  // Restricts to string only<br>}<br><br>const BadBaseButton: React.FC&lt;BadBaseButton&gt; = ({ onClick, text }) =&gt; (<br>  &lt;button onClick={onClick}&gt;{text}&lt;/button&gt;<br>);<br><br>// Violates LSP by changing prop structure and behavior<br>interface BadPrimaryButton {<br>  label: string;  // Different prop name<br>  onAction: (e: React.MouseEvent) =&gt; Promise&lt;void&gt;;  // Different type<br>}<br><br>const BadPrimaryButton: React.FC&lt;BadPrimaryButton&gt; = ({ label, onAction }) =&gt; {<br>  const handleClick = async (e: React.MouseEvent) =&gt; {<br>    await onAction(e);<br>  };<br><br>  return &lt;button onClick={handleClick}&gt;{label.toUpperCase()}&lt;/button&gt;;<br>};<br><br>// Usage shows incompatibility<br>const BadExample: React.FC = () =&gt; {<br>  const handleClick = () =&gt; console.log(&#39;clicked&#39;);<br>  <br>  return (<br>    &lt;div&gt;<br>      &lt;BadBaseButton <br>        onClick={handleClick} <br>        text=&quot;Click me&quot; <br>      /&gt;<br>      <br>      {/* Won&#39;t work! Different props and behavior */}<br>      &lt;BadPrimaryButton <br>        label=&quot;Click me&quot;<br>        onAction={async (e) =&gt; console.log(&#39;clicked&#39;)} <br>      /&gt;<br>    &lt;/div&gt;<br>  );<br>};</pre><p><strong>Following LSP:</strong> It helps to ensure<strong> </strong>base props are extended consistently, the same onClick type throughout, components are interchangeable &amp; add features without breaking the base contract.</p><pre>// ✅ GOOD EXAMPLE - Following LSP<br>interface GoodBaseButtonProps {<br>  onClick: () =&gt; void;<br>  children: React.ReactNode;<br>}<br><br>const GoodBaseButton: React.FC&lt;GoodBaseButtonProps&gt; = ({ onClick, children }) =&gt; (<br>  &lt;button onClick={onClick}&gt;{children}&lt;/button&gt;<br>);<br><br>// Properly extends base props<br>interface GoodPrimaryButtonProps extends GoodBaseButtonProps {<br>  variant?: &#39;solid&#39; | &#39;outline&#39;;  // Optional additional prop<br>}<br><br>const GoodPrimaryButton: React.FC&lt;GoodPrimaryButtonProps&gt; = ({ <br>  onClick, <br>  children, <br>  variant = &#39;solid&#39; <br>}) =&gt; {<br>  const className = variant === &#39;solid&#39; ? &#39;bg-blue-500&#39; : &#39;border-blue-500&#39;;<br>  <br>  return (<br>    &lt;button onClick={onClick} className={className}&gt;<br>      {children}<br>    &lt;/button&gt;<br>  );<br>};<br><br>// Usage shows compatibility<br>const GoodExample: React.FC = () =&gt; {<br>  const handleClick = () =&gt; console.log(&#39;clicked&#39;);<br>  <br>  return (<br>    &lt;div&gt;<br>      {/* Both components can use the same handler */}<br>      &lt;GoodBaseButton onClick={handleClick}&gt;<br>        Click me<br>      &lt;/GoodBaseButton&gt;<br>      <br>      &lt;GoodPrimaryButton onClick={handleClick} variant=&quot;solid&quot;&gt;<br>        Click me<br>      &lt;/GoodPrimaryButton&gt;<br>    &lt;/div&gt;<br>  );<br>};</pre><h3>4. Interface Segregation Principle (ISP)</h3><ul><li><strong>Definition</strong>: Clients should not be forced to depend on interfaces they do not use.</li><li><strong>In React</strong>: Ensure that components accept only the props they need, and use custom hooks to separate different concerns.</li></ul><p><strong>Not following ISP:</strong> In this example, the extended interface is forced to implement all props even if it doesn’t need them.</p><pre>// ❌ BAD EXAMPLE - Violating ISP<br>interface ButtonProps {<br>  label: string;<br>  onClick: () =&gt; void;<br>  icon: string;        // Not all buttons need icons<br>  loading: boolean;    // Not all buttons need loading state<br>  disabled: boolean;   // Not all buttons need disabled state<br>}<br><br>const Button: React.FC&lt;ButtonProps&gt; = ({ label, onClick, icon, loading, disabled }) =&gt; {<br>  return (<br>    &lt;button onClick={onClick} disabled={disabled}&gt;<br>      {loading ? &quot;Loading...&quot; : label}<br>      {icon &amp;&amp; &lt;span&gt;{icon}&lt;/span&gt;}<br>    &lt;/button&gt;<br>  );<br>};</pre><p><strong>Following ISP:</strong> Now, let’s refactor this code by Segregating interfaces for different aspects of the button.</p><pre>// ✅ GOOD EXAMPLE - Following ISP<br>interface BasicButtonProps {<br>  label: string;<br>  onClick: () =&gt; void;<br>}<br><br>interface LoadingButtonProps extends BasicButtonProps {<br>  loading: boolean;<br>}<br><br>// Simple button without unnecessary props<br>const SimpleButton: React.FC&lt;BasicButtonProps&gt; = ({ label, onClick }) =&gt; {<br>  return &lt;button onClick={onClick}&gt;{label}&lt;/button&gt;;<br>};<br><br>// Button with loading state<br>const LoadingButton: React.FC&lt;LoadingButtonProps&gt; = ({ label, onClick, loading }) =&gt; {<br>  return (<br>    &lt;button onClick={onClick}&gt;<br>      {loading ? &quot;Loading...&quot; : label}<br>    &lt;/button&gt;<br>  );<br>};</pre><h3>5. Dependency Inversion Principle (DIP)</h3><ul><li><strong>Definition</strong>: High-level modules should not depend on low-level modules; both should depend on abstractions.</li><li><strong>In React</strong>: Use context, hooks, or dependency injection to invert dependencies.</li></ul><p><strong>Not following DIP:</strong> In this example, the BadNotificationButton component directly depends on concrete ToastNotification.</p><pre>// ❌ BAD EXAMPLE - Violating DIP<br>class ToastNotification {<br>  show(message: string) {<br>    // Direct implementation of toast<br>    console.log(`Toast: ${message}`);<br>    // Imagine this actually shows a toast<br>  }<br>}<br><br>// Component directly depends on concrete implementation<br>const BadNotificationButton: React.FC = () =&gt; {<br>  // Direct instantiation - tightly coupled<br>  const toaster = new ToastNotification();<br><br>  const handleClick = () =&gt; {<br>    toaster.show(&#39;Button clicked!&#39;);  // Directly coupled to toast<br>  };<br><br>  return (<br>    &lt;button onClick={handleClick}&gt;<br>      Show Notification<br>    &lt;/button&gt;<br>  );<br>};</pre><p><strong>Following DIP: </strong>We refactored the code by wrapping it with the createContext API, ensuring adherence to the Dependency Inversion Principle (DIP). This approach minimizes tight coupling by promoting loose dependencies and enhances the overall modularity and flexibility of the code.</p><pre>// ✅ GOOD EXAMPLE - Following DIP<br>// Define the abstraction<br>interface NotificationService {<br>  notify(message: string): void;<br>}<br><br>// Concrete implementations<br>class ToastService implements NotificationService {<br>  notify(message: string) {<br>    console.log(`Toast: ${message}`);<br>    // Actual toast implementation<br>  }<br>}<br><br>class AlertService implements NotificationService {<br>  notify(message: string) {<br>    console.log(`Alert: ${message}`);<br>    // Actual alert implementation<br>  }<br>}<br><br>// Context for dependency injection<br>const NotificationContext = React.createContext&lt;NotificationService | null&gt;(null);<br><br>// Provider component<br>interface NotificationProviderProps {<br>  service: NotificationService;<br>  children: React.ReactNode;<br>}<br><br>const NotificationProvider: React.FC&lt;NotificationProviderProps&gt; = ({<br>  service,<br>  children<br>}) =&gt; (<br>  &lt;NotificationContext.Provider value={service}&gt;<br>    {children}<br>  &lt;/NotificationContext.Provider&gt;<br>);<br><br>// Custom hook for using notifications<br>const useNotification = () =&gt; {<br>  const service = React.useContext(NotificationContext);<br>  if (!service) {<br>    throw new Error(&#39;useNotification must be used within NotificationProvider&#39;);<br>  }<br>  return service;<br>};<br><br>// Button component depends on abstraction<br>const GoodNotificationButton: React.FC&lt;{<br>  message: string;<br>}&gt; = ({ message }) =&gt; {<br>  const notificationService = useNotification();<br><br>  const handleClick = () =&gt; {<br>    notificationService.notify(message);<br>  };<br><br>  return (<br>    &lt;button <br>      onClick={handleClick}<br>      className=&quot;px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600&quot;<br>    &gt;<br>      Show Notification<br>    &lt;/button&gt;<br>  );<br>};<br><br>// Example Usage<br>const App: React.FC = () =&gt; {<br>  // Can easily switch between services<br>  const toastService = new ToastService();<br>  const alertService = new AlertService();<br><br>  return (<br>    &lt;div className=&quot;p-4&quot;&gt;<br>      {/* Using Toast Service */}<br>      &lt;NotificationProvider service={toastService}&gt;<br>        &lt;div className=&quot;mb-4&quot;&gt;<br>          &lt;h2 className=&quot;text-lg font-bold mb-2&quot;&gt;Toast Notifications&lt;/h2&gt;<br>          &lt;GoodNotificationButton message=&quot;Toast notification!&quot; /&gt;<br>        &lt;/div&gt;<br>      &lt;/NotificationProvider&gt;<br><br>      {/* Using Alert Service */}<br>      &lt;NotificationProvider service={alertService}&gt;<br>        &lt;div&gt;<br>          &lt;h2 className=&quot;text-lg font-bold mb-2&quot;&gt;Alert Notifications&lt;/h2&gt;<br>          &lt;GoodNotificationButton message=&quot;Alert notification!&quot; /&gt;<br>        &lt;/div&gt;<br>      &lt;/NotificationProvider&gt;<br>    &lt;/div&gt;<br>  );<br>};</pre><p>By following these principles, you can ensure that your React components remain consistent, substitutable, and reliable, leading to more maintainable and scalable applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1695d12e79aa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/mighty-ghost-hack/solid-principles-in-react-for-cleaner-and-scalable-code-1695d12e79aa">SOLID Principles in React for Cleaner and Scalable Code</a> was originally published in <a href="https://medium.com/mighty-ghost-hack">Mighty ghost hack</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>