<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brad Hankee</title>
    <description>The latest articles on DEV Community by Brad Hankee (@bhankee).</description>
    <link>https://dev.to/bhankee</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F180402%2Fffe942fc-1dc1-43b2-90b0-08392fc9980f.png</url>
      <title>DEV Community: Brad Hankee</title>
      <link>https://dev.to/bhankee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bhankee"/>
    <language>en</language>
    <item>
      <title>How I Built an Evaluation Pipeline for AI Image Generation</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Fri, 20 Feb 2026 19:04:10 +0000</pubDate>
      <link>https://dev.to/bhankee/how-i-built-an-evaluation-pipeline-for-ai-image-generation-2epf</link>
      <guid>https://dev.to/bhankee/how-i-built-an-evaluation-pipeline-for-ai-image-generation-2epf</guid>
      <description>&lt;h2&gt;
  
  
  We automated blog image generation with Imagen 4. It worked beautifully... except when it didn't.
&lt;/h2&gt;

&lt;p&gt;Sometimes the AI would sneak text into images despite explicit instructions not to. Here's how we fixed it with automated evaluation. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;We're generating retro hero images for blog posts at &lt;a href="https://vetswhocode.io/blogs/blog" rel="noopener noreferrer"&gt;Vets Who Code&lt;/a&gt;. The requirements were strict:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bold navy/red/white color palette only&lt;/li&gt;
&lt;li&gt;NO text or typography&lt;/li&gt;
&lt;li&gt;Retro poster aesthetic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Imagen 4 is powerful, but non-deterministic. We'd get 8 perfect images, then 2 with random text. Manual QA doesn't scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Automated Evaluation
&lt;/h2&gt;

&lt;p&gt;We built a test harness using Gemini Vision to grade Imagen's outputs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Generate test images&lt;/strong&gt;&lt;br&gt;
Run the same prompts 10x to measure consistency&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Automated validation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Gemini Vision to detect text (even single letters)&lt;/li&gt;
&lt;li&gt;Validate color palette adherence&lt;/li&gt;
&lt;li&gt;Check style consistency&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Track metrics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pass rate across test cases&lt;/li&gt;
&lt;li&gt;Violation patterns (text vs colors vs style)&lt;/li&gt;
&lt;li&gt;Save failed images for inspection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Iterate on prompts&lt;/strong&gt;&lt;br&gt;
Based on eval data we discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moving "NO TEXT" to the top of the prompt improved adherence by 40%&lt;/li&gt;
&lt;li&gt;Repeating constraints in multiple places reduced violations BUT only to an extent&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Too many NOs equal a YES
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This turned out to be much like a human interaction with children. The more you tell them 'NO' the more likely it is to fail.
We found out that the amount of negative constrains (no letters, no text, no numbers etc.) turned out to be a bell curved chart in that having 0 did not work, adding a few at deliberate locations worked well, adding more turned out to fail more. WHY?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Too many of these instances turned out to flood the LLM with those words and even though we were stating NOT to include them they saw the word count to turn into these might be important to have.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;When using AI in production:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Assume non-determinism&lt;/strong&gt; — what works once might fail the 10th time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use AI to evaluate AI&lt;/strong&gt; — Gemini Vision is great for validating image outputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make evals fast&lt;/strong&gt; — automated testing lets you iterate rapidly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track metrics over time&lt;/strong&gt; — you want to know if model updates break your workflow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Brad&lt;br&gt;
&lt;a href="https://www.bradhankee.com/" rel="noopener noreferrer"&gt;bradhankee.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>genai</category>
      <category>softwareengineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>The KC-10 Was My First Codebase — I Just Didn’t Know It Yet</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Mon, 08 Dec 2025 15:45:02 +0000</pubDate>
      <link>https://dev.to/bhankee/the-kc-10-was-my-first-codebase-i-just-didnt-know-it-yet-11c7</link>
      <guid>https://dev.to/bhankee/the-kc-10-was-my-first-codebase-i-just-didnt-know-it-yet-11c7</guid>
      <description>&lt;h2&gt;
  
  
  From KC-10 Aircraft to Codebases: How I Learned System Design Before Computer Science
&lt;/h2&gt;

&lt;p&gt;Before I ever wrote software professionally, I was an electrician and pneumatics specialist on KC-10 aircraft. I didn’t call it “system design,” but that’s exactly what it was — understanding how large, interconnected systems behave, fail, and recover. When I later moved into software engineering, so many principles felt familiar that it almost seemed like I had been training for it without realizing it.&lt;/p&gt;




&lt;h2&gt;
  
  
  System Design: Schematics → Architecture
&lt;/h2&gt;

&lt;p&gt;Working on the KC-10 meant thinking in terms of systems, not isolated parts. Electrical, pneumatics, hydraulics, avionics all felt like everything relied on something else.&lt;/p&gt;

&lt;p&gt;That mindset maps directly to software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inputs/outputs&lt;/strong&gt; in aircraft systems behave like APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies and redundancy&lt;/strong&gt; mirror service architecture and failover strategies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failure modes&lt;/strong&gt; taught me to ask not just “Does this work?” but “What happens when it doesn’t?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The wiring diagrams I used to study feel a lot like the architecture diagrams I use today. Both describe how a complex system communicates and reacts under stress.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting &amp;amp; Debugging: Multimeters → Logs
&lt;/h2&gt;

&lt;p&gt;Aircraft discrepancies rarely came with clear symptoms. To fix a problem, you had to reproduce it, trace the system end-to-end, and validate the fix with zero guesswork.&lt;/p&gt;

&lt;p&gt;That is &lt;strong&gt;exactly&lt;/strong&gt; how debugging works in software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reproduce the issue under the right conditions&lt;/li&gt;
&lt;li&gt;Trace the flow through each subsystem or function&lt;/li&gt;
&lt;li&gt;Form hypotheses and test them&lt;/li&gt;
&lt;li&gt;Confirm the solution with checks and monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether I’m holding a multimeter or scanning logs, the approach is identical: systematic, thorough, and evidence-driven.&lt;/p&gt;




&lt;h2&gt;
  
  
  Oversight &amp;amp; Quality: 100% or It Doesn’t Fly
&lt;/h2&gt;

&lt;p&gt;On an aircraft, “good enough” is unacceptable. Everything is inspected, documented, and verified. Some tasks required multiple sign-offs because real lives depended on the result.&lt;/p&gt;

&lt;p&gt;That experience shaped how I approach engineering quality today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code reviews = peer inspections&lt;/li&gt;
&lt;li&gt;Testing and CI = functional and system checks&lt;/li&gt;
&lt;li&gt;Documentation = our modern technical orders&lt;/li&gt;
&lt;li&gt;Monitoring = continuous post-flight inspection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If code is going to “fly” in production, it should be something I’d confidently sign my name to.&lt;/p&gt;




&lt;h2&gt;
  
  
  Continuous Improvement &amp;amp; Mentorship
&lt;/h2&gt;

&lt;p&gt;On the flight line, improvement was part of the culture. We refined procedures, looked for better ways to troubleshoot, and coached junior airmen so the whole team grew stronger.&lt;/p&gt;

&lt;p&gt;In software, that became:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring and reducing tech debt&lt;/li&gt;
&lt;li&gt;Sharing context with junior devs&lt;/li&gt;
&lt;li&gt;Running retros to identify process improvements&lt;/li&gt;
&lt;li&gt;Building a culture where quality and learning compound over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It wasn’t just about fixing today’s issues, it was about making tomorrow’s work safer, faster, and smarter.&lt;/p&gt;




&lt;h2&gt;
  
  
  How This Shapes Me as an Engineer
&lt;/h2&gt;

&lt;p&gt;My aviation experience trained me to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Think in systems&lt;/li&gt;
&lt;li&gt;Debug with discipline&lt;/li&gt;
&lt;li&gt;Treat quality as non-negotiable&lt;/li&gt;
&lt;li&gt;Improve the team, not just the task&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I learned programming later, but the foundations of engineering — systems thinking, troubleshooting, ownership, and mentorship — were already there. The aircraft just taught them to me first.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>softwareengineering</category>
      <category>systems</category>
      <category>web</category>
    </item>
    <item>
      <title>Software Fun-duh-mentals - DNS</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Thu, 04 Dec 2025 19:56:12 +0000</pubDate>
      <link>https://dev.to/bhankee/software-fun-duh-mentals-dns-3a1n</link>
      <guid>https://dev.to/bhankee/software-fun-duh-mentals-dns-3a1n</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;DNS: The Underrated Backbone of Scale and Security&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When most developers hear &lt;strong&gt;DNS&lt;/strong&gt;, they think “the thing that turns &lt;code&gt;google.com&lt;/code&gt; into an IP address.” And while that’s technically true, it wildly undersells what DNS actually represents in modern software engineering.&lt;/p&gt;

&lt;p&gt;DNS (Domain Name System) is the routing layer of the internet. It’s the first service your users interact with—often before your load balancers, CDN, or backend infrastructure even get a chance. Because of that, DNS plays a much bigger role in application &lt;strong&gt;performance&lt;/strong&gt;, &lt;strong&gt;scaling&lt;/strong&gt;, and &lt;strong&gt;security&lt;/strong&gt; than most engineers initially realize.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What DNS Actually Does&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;DNS is a distributed, hierarchical system that maps human-friendly names (like &lt;code&gt;example.com&lt;/code&gt;) to machine-friendly information (like IP addresses, mail servers, or service endpoints).&lt;/p&gt;

&lt;p&gt;When a user types your domain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The browser asks the DNS resolver for the IP address&lt;/li&gt;
&lt;li&gt;The resolver follows DNS hierarchy (root → TLD → authoritative)&lt;/li&gt;
&lt;li&gt;It returns the final answer—your application’s entry point&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that you know the basics, let’s talk about where DNS becomes a &lt;em&gt;software engineering lever&lt;/em&gt; rather than just a lookup table.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;DNS as a Scaling Tool&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Scaling isn’t just about bigger servers or more containers—it’s about directing traffic intelligently. DNS is one of the first layers that lets you do that.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Global Load Distribution&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DNS can route users to different servers based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Geolocation&lt;/strong&gt; (send users to the closest region)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Latency&lt;/strong&gt; (route to lowest-latency endpoint)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks&lt;/strong&gt; (automatically remove unhealthy endpoints)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weighted routing&lt;/strong&gt; (gradually shift traffic during deployments)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why modern SaaS companies rely on DNS providers like Cloudflare — turning DNS into a &lt;em&gt;traffic control system&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you’ve ever:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rolled out features region-by-region&lt;/li&gt;
&lt;li&gt;Slowly shifted from v1 to v2 of an API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DNS was likely helping orchestrate that rollout.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. CDN Enablement&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;CDNs (Cloudflare, Fastly etc.) rely on DNS routing to direct clients to the nearest cache edge. Without DNS, global content acceleration doesn’t exist.&lt;/p&gt;

&lt;p&gt;If you want to scale, really scale, DNS is the gatekeeper to distributing workloads worldwide.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. High Availability and Failover&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DNS enables infrastructure patterns like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Active–active failover&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Active–passive failover&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Disaster recovery routing&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a region goes down, DNS can instantly reroute traffic to a healthy region—often without users noticing anything happened.&lt;/p&gt;

&lt;p&gt;This turns DNS into a &lt;em&gt;resilience layer&lt;/em&gt; in distributed software architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;DNS as a Security Layer&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;If DNS is the front door to your system, it’s also one of the best places to enforce security.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. DNSSEC (Domain Integrity Protection)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DNS wasn’t originally built with authentication in mind, which led to vulnerabilities like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS spoofing&lt;/li&gt;
&lt;li&gt;Cache poisoning&lt;/li&gt;
&lt;li&gt;Man-in-the-middle attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;DNSSEC&lt;/strong&gt; adds cryptographic signatures to DNS responses so clients can verify authenticity. It doesn’t encrypt traffic, but it makes sure attackers can’t lie about where your domain points.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. Traffic Filtering and Threat Mitigation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Modern DNS providers offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DDoS absorption at the DNS layer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bot filtering&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Malicious domain blocking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zero-trust access to internal services&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before a request ever touches your app, DNS can decide whether it’s allowed to.&lt;/p&gt;

&lt;p&gt;As traffic increases—or becomes more hostile—this becomes essential.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. Reducing Attack Surface&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;DNS lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hide internal services behind private or split-horizon DNS&lt;/li&gt;
&lt;li&gt;Remove unused records that expose infrastructure&lt;/li&gt;
&lt;li&gt;Rotate underlying infrastructure without changing public endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your DNS layer becomes a shield—not just a switchboard.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Why DNS Belongs in Every Engineer’s Toolkit&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;DNS is often treated as something DevOps handles, but in reality:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend engineers rely on fast DNS for low TTFB&lt;/li&gt;
&lt;li&gt;Backend engineers rely on DNS for service discovery&lt;/li&gt;
&lt;li&gt;AI engineers rely on reliable endpoints for model inference calls&lt;/li&gt;
&lt;li&gt;Ops/SRE teams rely on DNS for routing and resilience&lt;/li&gt;
&lt;li&gt;Security teams rely on DNS for domain integrity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding DNS makes you a &lt;em&gt;better architect&lt;/em&gt;, not just someone who knows how domains work.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.bradhankee.com/" rel="noopener noreferrer"&gt;Brad Hankee&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>systemdesign</category>
      <category>networking</category>
      <category>security</category>
      <category>performance</category>
    </item>
    <item>
      <title>How I Built an AI That Can Make Developers Cry (And Learn)</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Thu, 20 Nov 2025 15:58:10 +0000</pubDate>
      <link>https://dev.to/bhankee/how-i-built-an-ai-that-can-make-developers-cry-and-learn-3jl8</link>
      <guid>https://dev.to/bhankee/how-i-built-an-ai-that-can-make-developers-cry-and-learn-3jl8</guid>
      <description>&lt;p&gt;🔥 You think you can handle AI roasting your web dev portfolio? Give it a shot while also getting lighthouse performance metrics and design feedback based on your actual site design.&lt;/p&gt;

&lt;p&gt;As a AI engineer and web developer, I wanted to build a product that would be both technically challenging and fun. So I built &lt;a href="https://roast-my-portfolio-ten.vercel.app/" rel="noopener noreferrer"&gt;Roast My Portfolio&lt;/a&gt; — an AI-powered web app that analyzes developer portfolio websites and (depending on the mode) either gives professional, actionable UX feedback, or completely roasts it with brutal honesty and sarcasm.&lt;/p&gt;

&lt;p&gt;It’s deployed live &lt;a href="https://roast-my-portfolio-ten.vercel.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt; if you think you can handle the feedback!&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 Tech at a Glance
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;React + Next.js + TypeScript (Vercel)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backend API&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;FastAPI (Python), deployed on Railway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI Models&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;LLM multi-mode via Groq (Llama 3.3 70B)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Automation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Lighthouse CLI for web performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Screenshot Capture&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Browserless&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth &amp;amp; DB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Supabase&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Vercel (FE), Railway (Dockerized BE)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  🚀 How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;User enters a portfolio URL and chooses “Roast” or “Serious” mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The backend scrapes the site, gathers content, captures a screenshot, and generates a Lighthouse performance report.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All of that gets bundled into a prompt (plus persona-based styling) and sent to the AI model (Groq).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The AI returns structured JSON:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "score": 7,
  "feedback": "...",
  "visual_design_feedback": "...",
  "suggestions": [...]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend displays the results using a custom UI with animated score graphics and metric visualizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  🤖 AI Prompt Strategy
&lt;/h3&gt;

&lt;p&gt;I built two prompts using LangChain templates:&lt;/p&gt;

&lt;p&gt;🔥 Roast Mode – sarcastic, witty, comedic tone using the Groq API.&lt;/p&gt;

&lt;p&gt;💼 Serious Mode – professional UX &amp;amp; design critique using Groq as well.&lt;/p&gt;

&lt;p&gt;A key setup was enforcing consistent JSON responses to keep parsing stable:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Return ONLY valid JSON, no markdown or additional commentary.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This allowed reliable extraction of feedback, score, and suggestions.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Challenges Solved
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;CORS &amp;amp; domain routing issues between Vercel and Railway.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Getting Docker builds to work with FastAPI and managing .env variables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling AI output consistency (LLMs love adding extra flourish).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making Lighthouse work without blocking performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoiding token overflow with prompt truncation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📈 What’s Next
&lt;/h3&gt;

&lt;p&gt;PDF export of roast results for sharing.&lt;/p&gt;

&lt;p&gt;“Before/After portfolio improvements” tracker.&lt;/p&gt;

&lt;p&gt;User accounts with analysis history.&lt;/p&gt;

&lt;p&gt;If you're exploring AI-powered tooling or want feedback on your portfolio (painful or professional), give it a try.&lt;/p&gt;

&lt;p&gt;👉 [Live Demo Link Here]&lt;br&gt;
🎯 Would love to hear your feedback and roast suggestions!&lt;/p&gt;

&lt;h3&gt;
  
  
  📝 Final Thoughts
&lt;/h3&gt;

&lt;p&gt;This project helped me bridge my front-end experience with backend AI engineering, and taught me a lot about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;AI model prompting strategies&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;LLM Structured outputs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrating custom datasets (screenshot + Lighthouse + scraped content)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re trying to make the jump into AI engineering — build something weird, something useful, or something hilarious. You’ll learn way faster.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>langchain</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Function Calling in LangChain: Turning Chatbots into Enterprise Copilots</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Thu, 30 Oct 2025 00:08:29 +0000</pubDate>
      <link>https://dev.to/bhankee/function-calling-in-langchain-turning-chatbots-into-enterprise-copilots-16io</link>
      <guid>https://dev.to/bhankee/function-calling-in-langchain-turning-chatbots-into-enterprise-copilots-16io</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7il0qntxe6akahmob46.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7il0qntxe6akahmob46.jpg" alt="vector image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Function Calling and Tool Calling in LangChain
&lt;/h2&gt;

&lt;p&gt;If you’ve been diving into &lt;strong&gt;LangChain&lt;/strong&gt;, you’ve probably noticed that it has a pretty elegant way of standardizing how LLMs interact with external tools — whether those are APIs, databases, or your own custom functions.&lt;/p&gt;

&lt;p&gt;At the heart of this design are &lt;strong&gt;function calling&lt;/strong&gt; and &lt;strong&gt;tool calling&lt;/strong&gt; — mechanisms that give the LLM structured ways to perform actions beyond text generation. In this post, I’ll walk through what they are, how they work, and why they’re so powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What Function Calling Actually Does
&lt;/h2&gt;

&lt;p&gt;Function calling lets an LLM decide &lt;strong&gt;when&lt;/strong&gt; and &lt;strong&gt;how&lt;/strong&gt; to use a function (or “tool”) you’ve defined. Instead of hard-coding logic for every possible task, you provide the LLM with a list of available tools and their schemas — and it figures out which one to call, if any.&lt;/p&gt;

&lt;p&gt;Here’s the magic part:&lt;br&gt;&lt;br&gt;
When the model determines a tool is needed, it returns a &lt;strong&gt;structured JSON object&lt;/strong&gt; specifying the tool name and the arguments it wants to use. LangChain handles the plumbing for you — executing the tool, appending its result back into the conversation history, and letting the LLM continue reasoning from there.&lt;/p&gt;

&lt;p&gt;This process looks like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The model receives a user query.
&lt;/li&gt;
&lt;li&gt;It decides whether a tool is needed.
&lt;/li&gt;
&lt;li&gt;If yes, it outputs the tool name + JSON arguments.
&lt;/li&gt;
&lt;li&gt;LangChain executes that tool.
&lt;/li&gt;
&lt;li&gt;The result is appended to the message list and sent back to the LLM.
&lt;/li&gt;
&lt;li&gt;The LLM continues, now with that new context.&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  ⚙️ Core Functions for Tool Handling in LangChain
&lt;/h2&gt;

&lt;p&gt;LangChain has made this pattern remarkably clean through a few key methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.bind_tools()&lt;/code&gt;&lt;/strong&gt; – attaches your tool definitions (schemas, descriptions, etc.) directly to a model call.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;.tool_calls()&lt;/code&gt;&lt;/strong&gt; – retrieves or inspects the tools the model actually invoked.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;create_tool_calling_agent()&lt;/code&gt;&lt;/strong&gt; – builds an agent that can manage multiple tools and handle parallel tool calls automatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These functions help standardize how you define, attach, and inspect tools — and make it easy to scale from a single function call to a multi-tool agent setup.&lt;/p&gt;


&lt;h2&gt;
  
  
  🧩 Example: Using &lt;code&gt;bind_tools()&lt;/code&gt; for Function Calling
&lt;/h2&gt;

&lt;p&gt;Let’s make this concrete with a simple example.&lt;/p&gt;

&lt;p&gt;Say you want your model to have access to a &lt;strong&gt;weather tool&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
The tool will take a city name and return fake weather data — just enough to illustrate how tool schemas and calls work.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.tools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="c1"&gt;# Step 1: Define your tool
&lt;/span&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Returns current weather for a given city.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;fake_weather&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Portland&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Rainy and 55°F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Austin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sunny and 82°F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;New York&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cloudy and 64°F&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;fake_weather&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Weather data unavailable&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Step 2: Initialize your model
&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o-mini&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Step 3: Bind your tool to the model
&lt;/span&gt;&lt;span class="n"&gt;model_with_tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind_tools&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# Step 4: Ask the model a question that may trigger a tool call
&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model_with_tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s the weather like in Portland today?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you run this, the LLM may decide it needs to call the &lt;code&gt;get_weather&lt;/code&gt; tool — and LangChain will automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate the structured JSON call with the correct arguments,&lt;/li&gt;
&lt;li&gt;Execute the function,&lt;/li&gt;
&lt;li&gt;Append the result to the message history,&lt;/li&gt;
&lt;li&gt;And return the combined final response.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you inspect the model’s internal state (for debugging), you can see what tools it used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tool_calls&lt;/span&gt;  &lt;span class="c1"&gt;# See what tools were invoked
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔄 Switching Between Models Is Easy
&lt;/h2&gt;

&lt;p&gt;One of the best aspects of LangChain’s function calling setup is how &lt;strong&gt;model-agnostic&lt;/strong&gt; it is. You can swap between OpenAI, Anthropic, or local models that support the same structured-function-calling interface with minimal changes. The schema for your tools stays the same — it’s the LLM that decides how to interpret and use them.&lt;/p&gt;

&lt;p&gt;That means once you’ve defined your tools, you can experiment with different providers or even run them in parallel to compare behavior.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Parallel Tool Calls
&lt;/h2&gt;

&lt;p&gt;LangChain’s architecture also allows the LLM to &lt;strong&gt;run multiple tool calls in parallel&lt;/strong&gt;. This can make certain workflows dramatically faster — for example, fetching data from multiple APIs at once or running several analysis functions simultaneously.&lt;/p&gt;

&lt;p&gt;You still define your tools declaratively, but LangChain’s internal orchestration ensures that execution happens efficiently under the hood.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔗 Common Tool Use Cases
&lt;/h2&gt;

&lt;p&gt;Some classic examples of tools you might expose include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API calls&lt;/strong&gt; – such as fetching weather, stock prices, or data from your own backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database queries&lt;/strong&gt; – using SQL or vector search for retrieval-augmented generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Computation utilities&lt;/strong&gt; – small functions like calculating dates, formatting text, or summarizing results.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these tools has a schema that tells the LLM what inputs it expects — and that schema is what allows the model to call it correctly using structured JSON.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Responsibility of Description
&lt;/h2&gt;

&lt;p&gt;With great power comes… well, a bit of responsibility.&lt;br&gt;
The better you describe your tools, the better the LLM performs.&lt;/p&gt;

&lt;p&gt;Each tool’s description should clearly explain &lt;strong&gt;what it does&lt;/strong&gt; and &lt;strong&gt;when to use it&lt;/strong&gt;. That’s how the model learns to make accurate choices about when to call (or not call) a tool.&lt;/p&gt;

&lt;p&gt;The LLM isn’t just executing code blindly — it’s reasoning about when calling a tool makes sense. As AI engineers, our job is to give it the right context and structure to make those decisions intelligently.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏢 How Function Calling Impacts Enterprise and Business
&lt;/h2&gt;

&lt;p&gt;For enterprises, &lt;strong&gt;function calling changes the game&lt;/strong&gt; in how AI integrates with existing systems.&lt;/p&gt;

&lt;p&gt;Instead of siloed AI chatbots, organizations can now build &lt;strong&gt;intelligent orchestration layers&lt;/strong&gt; that sit on top of internal APIs, CRMs, databases, and analytics platforms.&lt;br&gt;
Here’s how it plays out in real business terms:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Seamless System Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Function calling lets an LLM act as the “brain” across multiple business tools — Salesforce, HubSpot, internal APIs, SQL databases, etc. It allows conversational interfaces that don’t just &lt;em&gt;talk&lt;/em&gt; but actually &lt;em&gt;act&lt;/em&gt; — fetching reports, creating tickets, or running queries in real time.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Governance and Standardization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Because tool schemas are explicitly defined, enterprises gain &lt;strong&gt;control and auditability&lt;/strong&gt;. You know exactly what the model can and can’t do, which functions it’s allowed to call, and how it’s supposed to format outputs (structured JSON).&lt;br&gt;
That’s critical for compliance, security, and scaling AI workflows safely.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Improved Efficiency and ROI&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Function calling cuts down on manual steps. Imagine a customer service model that calls a refund API, updates a database, and emails the customer — all within one reasoning loop.&lt;br&gt;
That’s time saved, fewer context switches, and measurable impact on team productivity.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Vendor Flexibility&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Since LangChain’s tool calling is &lt;strong&gt;model-agnostic&lt;/strong&gt;, businesses can swap or mix LLM providers (OpenAI, Anthropic, Mistral, etc.) without rewriting their integration layer.&lt;br&gt;
The function schemas remain constant — the intelligence layer becomes modular and future-proof.&lt;/p&gt;

&lt;p&gt;In short, function calling turns LLMs from “smart typists” into &lt;strong&gt;operational copilots&lt;/strong&gt; that can take action within enterprise systems safely and predictably.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Function calling and tool calling in LangChain unlock a whole new level of composability. Instead of coding static flows, you’re building &lt;strong&gt;dynamic reasoning systems&lt;/strong&gt; that can use external knowledge and computation whenever needed.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>langchain</category>
      <category>developer</category>
    </item>
    <item>
      <title>“Don’t Chain Yourself Down — Graph It Out! 🔗 (LangGraph, Memory, and the Future of AI Workflows)”</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Wed, 22 Oct 2025 15:07:58 +0000</pubDate>
      <link>https://dev.to/bhankee/dont-chain-yourself-down-graph-it-out-langgraph-memory-and-the-future-of-ai-workflows-1i4f</link>
      <guid>https://dev.to/bhankee/dont-chain-yourself-down-graph-it-out-langgraph-memory-and-the-future-of-ai-workflows-1i4f</guid>
      <description>&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkenj33rcg2ueagbrngt.jpg" alt="image of a chain" width="800" height="535"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Understanding LangGraph: Building Smarter, Stateful AI Workflows
&lt;/h2&gt;

&lt;p&gt;LangGraph has recently become one of my favorite tools from the LangChain ecosystem — and for good reason. If you’ve ever found yourself struggling to manage multi-step AI reasoning, dynamic state, or complex tool orchestration, LangGraph feels like that missing link in the chain(insert pun here).&lt;/p&gt;

&lt;p&gt;So what is LangGraph and when you should use it instead of standard LangChain, and some of its most exciting features like &lt;strong&gt;reducers&lt;/strong&gt;, &lt;strong&gt;super-steps&lt;/strong&gt;, &lt;strong&gt;memory checkpointing&lt;/strong&gt;, and even a bit of time travel.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is LangGraph?
&lt;/h2&gt;

&lt;p&gt;LangGraph is an extension of LangChain designed for &lt;strong&gt;stateful, graph-based AI applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like this: LangChain lets you build chains (step-by-step sequences).&lt;br&gt;
LangGraph lets you build &lt;strong&gt;graphs&lt;/strong&gt; — dynamic, branching workflows where each node can make decisions and carry forward memory and state.&lt;/p&gt;

&lt;p&gt;If LangChain is a pipeline, LangGraph is the traffic control system for multiple pipelines that can interact, merge, and loop intelligently.&lt;/p&gt;

&lt;p&gt;This means it’s perfect for cases like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-agent reasoning (AI agents collaborating or debating)&lt;/li&gt;
&lt;li&gt;Conversational memory over long sessions&lt;/li&gt;
&lt;li&gt;Stateful apps like chatbots, assistants, and copilots&lt;/li&gt;
&lt;li&gt;Complex data processing pipelines&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  When to Use LangGraph Over LangChain
&lt;/h2&gt;

&lt;p&gt;LangChain is amazing for &lt;strong&gt;linear workflows&lt;/strong&gt; — when you know the exact steps your model will take.&lt;br&gt;
But when you start needing &lt;strong&gt;adaptive logic&lt;/strong&gt;, where each step might depend on multiple previous results or user states, that’s when LangGraph shines.&lt;/p&gt;

&lt;p&gt;To simplify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Use LangChain&lt;/strong&gt; for predictable, short, single-pass reasoning.&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Use LangGraph&lt;/strong&gt; when you need looping, branching, memory, or dynamic control flow.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  State Management: Reducers and Super-Steps
&lt;/h2&gt;

&lt;p&gt;LangGraph utilizes the concept of &lt;strong&gt;state&lt;/strong&gt;, and it’s managed using what’s called a &lt;strong&gt;reducer&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;If you come from the React or Redux world — this should feel like your jam.&lt;br&gt;
Reducers take the &lt;strong&gt;previous state&lt;/strong&gt; and the &lt;strong&gt;new input&lt;/strong&gt;, and return the &lt;strong&gt;next state&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This makes the graph deterministic and inspectable — every node and edge mutation is explicit. No more guessing what happened mid-run.&lt;/p&gt;

&lt;p&gt;And then there’s the concept of a &lt;strong&gt;super-step&lt;/strong&gt; — essentially a full pass over all active nodes in your graph.&lt;br&gt;
Each super-step updates state across nodes, synchronously, so you can reason about your app in cycles rather than chaos.&lt;/p&gt;


&lt;h2&gt;
  
  
  Memory and Checkpointing
&lt;/h2&gt;

&lt;p&gt;This is where LangGraph really flexes.&lt;/p&gt;

&lt;p&gt;It includes built-in &lt;strong&gt;checkpointing&lt;/strong&gt;, which means you can save, reload, and “time travel” through the states of your graph.&lt;br&gt;
This is huge for debugging, long-running conversations, or AI workflows that evolve over time.&lt;/p&gt;

&lt;p&gt;Think of it like version control for your agent’s brain.&lt;/p&gt;

&lt;p&gt;You can inspect how your graph reasoned at step 5 vs. step 50, and even branch from a checkpoint to explore a new direction.&lt;/p&gt;

&lt;p&gt;This persistent memory layer integrates tightly with &lt;strong&gt;LangSmith&lt;/strong&gt;, LangChain’s observability platform.&lt;/p&gt;


&lt;h2&gt;
  
  
  Visualizing It: Nodes, Memory, and Checkpoints
&lt;/h2&gt;

&lt;p&gt;Here’s a quick visualization of how LangGraph keeps track of memory and checkpoints between nodes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph TD
    A[Start Node] --&amp;gt;|Adds user message| B[Model Node]
    B --&amp;gt;|Generates response| C[Memory Checkpoint]
    C --&amp;gt;|Saves to SQLite or LangSmith| D[Checkpoint Store]
    D --&amp;gt;|Reload / Time Travel| B
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 Each run through the graph:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The &lt;strong&gt;Start Node&lt;/strong&gt; initializes or updates the state.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Model Node&lt;/strong&gt; processes and updates that state.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Checkpoint&lt;/strong&gt; stores that state snapshot.&lt;/li&gt;
&lt;li&gt;You can &lt;strong&gt;restore&lt;/strong&gt; from any checkpoint and continue reasoning.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s simple, powerful, and makes debugging or branching your agent’s memory trivial.&lt;/p&gt;




&lt;h2&gt;
  
  
  LangSmith Integration
&lt;/h2&gt;

&lt;p&gt;LangSmith is your &lt;strong&gt;AI debugger and performance tracker&lt;/strong&gt;.&lt;br&gt;
When you run LangGraph with LangSmith, every node, state update, and tool call is logged automatically. You can replay runs, visualize reasoning chains, and monitor metrics in real time.&lt;/p&gt;

&lt;p&gt;In short — it’s not just a dev tool, it’s your AI workflow observatory.&lt;/p&gt;


&lt;h2&gt;
  
  
  Built-in Serper Wrapper
&lt;/h2&gt;

&lt;p&gt;LangGraph and LangChain come with handy tool integrations — one of the most useful being the &lt;strong&gt;Google Serper API wrapper&lt;/strong&gt;.&lt;br&gt;
It’s a quick way to give your agents access to live search results.&lt;/p&gt;

&lt;p&gt;Here’s how you can run a quick query using Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from langchain_community.utilities import GoogleSerperAPIWrapper

serper = GoogleSerperAPIWrapper()
serper.run("What is the capital of France?")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you guessed it — the model would return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Paris"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can easily be integrated into a LangGraph node as one of your tools, letting your agents pull in real-time context dynamically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Time Travel with Checkpoint IDs
&lt;/h2&gt;

&lt;p&gt;Remember those checkpoints we talked about earlier?&lt;br&gt;
You can actually use them to &lt;strong&gt;time travel&lt;/strong&gt; in LangGraph.&lt;/p&gt;

&lt;p&gt;Each checkpoint gets a unique ID, and you can restore or fork from that point in the graph.&lt;br&gt;
This allows you to explore “what-if” scenarios without rerunning everything from scratch — perfect for research, testing, or debugging reasoning drift in long sessions.&lt;/p&gt;

&lt;p&gt;Imagine jumping back to the moment before your AI made a bad decision… and sending it down a smarter path. 🕰️&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;LangGraph feels like the evolution of LangChain — not a replacement, but a level-up for developers building &lt;strong&gt;persistent, intelligent, multi-agent&lt;/strong&gt; systems.&lt;/p&gt;

&lt;p&gt;If you’ve hit the limits of simple chains, give graphs a try.&lt;br&gt;
The ability to reason over state, checkpoint memory, and visualize logic flows will make your AI apps not only smarter but also far more maintainable.&lt;/p&gt;




&lt;p&gt;– Brad&lt;br&gt;
&lt;a href="https://www.bradhankee.com/" rel="noopener noreferrer"&gt;Brad Hankee&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Building the bridge between web-dev and AI systems.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>langchain</category>
      <category>langgraph</category>
      <category>aiengineering</category>
      <category>frontendai</category>
    </item>
    <item>
      <title>Stop Waiting Around: Async &amp; Await in Python Explained</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Thu, 02 Oct 2025 13:30:11 +0000</pubDate>
      <link>https://dev.to/bhankee/stop-waiting-around-async-await-in-python-explained-44ib</link>
      <guid>https://dev.to/bhankee/stop-waiting-around-async-await-in-python-explained-44ib</guid>
      <description>&lt;p&gt;Hey JavaScript… Python’s got async too!&lt;/p&gt;

&lt;p&gt;So what exactly is async, and why should you care about it in Python?&lt;/p&gt;

&lt;p&gt;Since Python has become the go-to language for AI, data, and backend services, understanding asynchronous programming is more important than ever. If you’re making calls to LLMs, APIs, or any external service, async gives you a powerful way to manage those operations without your program sitting idle and wasting time.&lt;/p&gt;

&lt;p&gt;What Async Actually Is&lt;/p&gt;

&lt;p&gt;Think of async as lightweight concurrency. It’s similar to threading or multiprocessing, but much simpler to write and more efficient in many cases.&lt;/p&gt;

&lt;p&gt;When you define a function with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;async def my_function():
    ...

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you’re not just making a normal function. Technically, you’re creating a coroutine — a special kind of function that can be paused and resumed.&lt;/p&gt;

&lt;p&gt;What Happens When You Call a Coroutine?&lt;/p&gt;

&lt;p&gt;Here’s the gotcha: if you just call it, you don’t actually run it. You get back a coroutine object. To execute it, you need the await keyword:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;result = await my_function()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That await tells Python: “Pause here until the coroutine is done, then give me the result.”&lt;/p&gt;

&lt;p&gt;So while the word “async” sounds non-blocking, the await line itself is blocking for that specific call.&lt;/p&gt;

&lt;p&gt;Enter the Event Loop&lt;/p&gt;

&lt;p&gt;The real magic comes from Python’s built-in event loop (provided by asyncio). The event loop is like a conductor for your coroutines. While one coroutine is waiting — say, for an API call — the loop can run another one in the meantime.&lt;/p&gt;

&lt;p&gt;This gives you concurrency without the complexity of threads.&lt;/p&gt;

&lt;p&gt;Running Multiple Coroutines&lt;/p&gt;

&lt;p&gt;One of the coolest features is asyncio.gather(). With it, you can schedule multiple coroutines to run “at once” (really, managed by the event loop):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import asyncio

async def first_run():
    await asyncio.sleep(1)
    return "First done"

async def second_run():
    await asyncio.sleep(2)
    return "Second done"

async def third_run():
    await asyncio.sleep(1)
    return "Third done"

async def main():
    output = await asyncio.gather(
        first_run(),
        second_run(),
        third_run()
    )
    print(output)

asyncio.run(main())


Output:

['First done', 'Second done', 'Third done']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even though second_run() takes longer, the others don’t wait around — the event loop keeps everything moving efficiently.&lt;/p&gt;

&lt;p&gt;Takeaway&lt;/p&gt;

&lt;p&gt;async and await give Python developers an elegant way to write concurrent code. Whether you’re working with LLMs, APIs, or just want your app to be more responsive, it’s a tool worth learning.&lt;/p&gt;

&lt;p&gt;So next time someone drops “coroutine” in your Slack thread, you’ll know what’s up. 😉&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>AI is now my Health Coach ... and it's working 🏋️</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Fri, 19 Sep 2025 18:21:34 +0000</pubDate>
      <link>https://dev.to/bhankee/ai-is-now-my-health-coach-and-its-working-1jil</link>
      <guid>https://dev.to/bhankee/ai-is-now-my-health-coach-and-its-working-1jil</guid>
      <description>&lt;h2&gt;
  
  
  Connecting My Smart Scale to Gemini LLM for Custom Daily Meal Plans
&lt;/h2&gt;

&lt;p&gt;Recently, I built a local app that connects my withings smart scale to Google's Gemini LLM and uses my real-time daily weight data to generate &lt;strong&gt;custom daily meal plans&lt;/strong&gt;. The goal: hit my target body weight while preserving as much lean mass as possible.&lt;/p&gt;

&lt;p&gt;This article breaks down the idea, the tech stack, and some key learnings — including how temperature values in LLMs can drastically affect the type of outputs you get.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built This
&lt;/h2&gt;

&lt;p&gt;I wanted a way to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically collect my weight data every morning.&lt;/li&gt;
&lt;li&gt;Feed that into an LLM with a dynamic and customized prompt.&lt;/li&gt;
&lt;li&gt;Get back a set of meals tailored to my caloric needs for that day — with a focus on protein intake to preserve muscle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of manually calculating macros and searching for recipes, the LLM now does all of this for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Stack
&lt;/h2&gt;

&lt;p&gt;Here's the setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Withings Smart Scale&lt;/strong&gt; – Syncs weight data daily (total, lean mass, fat mass).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; – language built with to get data and hook into LLM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini LLM&lt;/strong&gt; – Takes weight, target weight, and some user preferences as input.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: Withings API is lets say... not great to use. After seeing this opinion all over I decided to make my life easy and use an applet from IFTTT to get my data into a google sheet. This made sense since this is a local app since it uses a very specific scale. &lt;/p&gt;

&lt;h2&gt;
  
  
  Sample of Output
&lt;/h2&gt;

&lt;p&gt;The only thing I give the LLM everyday are the proteins I have and plan to eat. In this case you can see if told it 85/15 ground beef and chicken thighs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujsp4v20v691p4er8s0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujsp4v20v691p4er8s0c.png" alt="chatbot image 1" width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnv7ki298ekpyvgk31zvi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnv7ki298ekpyvgk31zvi.png" alt="chatbot image 2" width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Progress so Far
&lt;/h2&gt;

&lt;p&gt;So far it's been great and I am down about 3 pounds. I added into the prompt to give me 2 options per meal so it would be somewhat flexible. I added history so that if it gives me a menu or item I do not have I can tell it and it will give me a better option such as this...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1848zhnmveaqd06iyget.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1848zhnmveaqd06iyget.png" alt="Show LLM history" width="800" height="136"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Working With LLM Temperature
&lt;/h2&gt;

&lt;p&gt;One of the most interesting discoveries was how &lt;strong&gt;temperature&lt;/strong&gt; affects the LLM's output.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low temperature (0.0–0.3)&lt;/strong&gt; → Very consistent results. The LLM mostly gives the same meal plan with minor variations. Good for keeping macros stable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium temperature (0.5–0.7)&lt;/strong&gt; → Adds more variety to meals. You get different recipes day to day, but they still hit macro targets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High temperature (0.8–1.0)&lt;/strong&gt; → Very creative. Sometimes too creative — you get exotic meals or unusual combinations that technically hit macros but might not be practical.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I found that &lt;strong&gt;0.5&lt;/strong&gt; was the sweet spot: balanced creativity without going off the rails.&lt;/p&gt;

&lt;p&gt;Here is a good example of the differences in the temperature. The first image is at .9 and the second at .1. You can see in the .1 the numbers are more consistent with almost always referencing 5oz for the portion sizes. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temp @ .9&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhndvh64e8okzuuibvatc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhndvh64e8okzuuibvatc.png" alt="temperature .9" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Temp @ .1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaby45fz3goe0k2ezvn9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmaby45fz3goe0k2ezvn9.png" alt="temperature .1" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Challenges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency&lt;/strong&gt;: Sometimes the LLM would under- or over-estimate calories. I had to add a check to ensure the total calories matched my target before saving the plan.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Variety vs. Adherence&lt;/strong&gt;: Too much meal variety made grocery shopping harder. I added an option to limit variety to a weekly rotation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;LLM temperature tuning matters a lot&lt;/strong&gt; — find the right level for your use case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automating meal plans saves mental energy&lt;/strong&gt; and reduces decision fatigue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preserving history enables deeper personalization&lt;/strong&gt; and makes it easier to see what works over time.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can check out the code in this &lt;a href="https://github.com/bhankee/health-ai" rel="noopener noreferrer"&gt;Repo&lt;/a&gt; if you would like. Thanks for reading!&lt;/p&gt;




</description>
      <category>gemini</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>TypeScript Primer ( Intro -&gt; Kinda Advanced)</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Mon, 12 Apr 2021 12:38:17 +0000</pubDate>
      <link>https://dev.to/bhankee/typescript-primer-intro-kinda-advanced-1l2o</link>
      <guid>https://dev.to/bhankee/typescript-primer-intro-kinda-advanced-1l2o</guid>
      <description>&lt;p&gt;Why TypeScript? I mean do we really want to write more code when the whole talk over the last decade has been about being more concise. &lt;br&gt;
YES! &lt;br&gt;
Yes, because writing a little more up front will help prevent all those production bugs that no one can afford. This can prevent you or others from drilling down call stacks in the browser dev tools as well.&lt;/p&gt;

&lt;p&gt;Another, and maybe the best reason, is the integrated documentation and IntelliSense that will make your life as a developer great since it feels like your coding with a rubber duck always looking over your shoulder screaming in your ear what you can and cannot do. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9rafs2vn3xy8o5hbjms.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa9rafs2vn3xy8o5hbjms.png" alt="Alt Text" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How does TypeScript work?&lt;br&gt;
TypeScript is written in .ts extension files. This allows the typescript compiler, which the user installs, to see these files and compile them into the vanilla JS files.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/jSSSOII8_oc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript Basics
&lt;/h2&gt;

&lt;p&gt;Type Inference(Implicit)- Typescript guesses the type for us&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;firstTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;
&lt;span class="c1"&gt;// This will show as: let firstTS: number&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type Annotations(Explicit) - We (devs) tell TypeScript the type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;firstTSAgain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;
&lt;span class="c1"&gt;// This will show as: let firstTS: number&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see both have same result as TypeScript will apply type &lt;strong&gt;number&lt;/strong&gt; when variable is declared with a value as &lt;strong&gt;number&lt;/strong&gt;. In this case there's no need to specify and be redundant. But if you are declaring a variable with out a value this is necessary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;missingVal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;

&lt;span class="c1"&gt;// You can also extend to have multiple types such as:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;moreOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Types and Interfaces
&lt;/h2&gt;

&lt;p&gt;One of the best parts of TypeScript is creating your own types which really allows you to control the structure of your code to a precise level. In this example we're making a type that can only be a certain string in a set of strings that we specify.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FavBand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Weezer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;GreenDay&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dropkick Murphys&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;coolBand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FavBand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tool&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Interfaces&lt;/strong&gt; are very much like types but more specific to data shapes such as objects like we see here. Notice in the property for &lt;strong&gt;drinksCoffee&lt;/strong&gt; the &lt;strong&gt;?&lt;/strong&gt;. This is to set this property to be optional and not mandatory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PathToSenJSDev&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;drinksCoffee&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dev&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PathToSenJSDev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;JS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   
    &lt;span class="na"&gt;drinksCoffee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;   
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Functions
&lt;/h3&gt;

&lt;p&gt;A basic version of a function is shown here where the parameters are set as a type and then after the parentheses the return value of the function is also specified. If a string were to be passed in the function call TypeScript would show an error on the spot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doubleMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;doubleMe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Mapped Types
&lt;/h3&gt;

&lt;p&gt;My favorite part of TypeScript so far. Think of mapped types as being able to apply specific functionality over another type.&lt;/p&gt;

&lt;p&gt;In this example we're going to use food to learn about mapped types by setting a recipe interface and then learning how to map over the interface and make the properties readonly and optional.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;

&lt;span class="c1"&gt;// Main Interface&lt;/span&gt;
 &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Recipe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;numIngred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;cookMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;BeefBourguignon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Recipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;numIngred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cookMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Simmer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Here we can modify &lt;/span&gt;
 &lt;span class="nx"&gt;BeefBourguignon&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;numIngred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="c1"&gt;// Create a readonly version that can map over a type &lt;/span&gt;
&lt;span class="c1"&gt;// Syntax [P in keyof T] is depicting "Property in keyof Type"&lt;/span&gt;

 &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ReadOnlyRecipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;readonly&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;readOnlyBeefBourguignon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReadOnlyRecipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Recipe&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;numIngred&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;cookMethod&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Simmer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;score&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Will not allow since this is now readonly&lt;/span&gt;
&lt;span class="c1"&gt;//  readOnlyBeefBourguignon.numIngred = 4&lt;/span&gt;


&lt;span class="c1"&gt;//Different version for adding optional to each property&lt;/span&gt;
 &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;OptionalProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;keyof&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;]?&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;This is just a primer that includes a small small set of features for TypeScript but I hope I picked some good use cases where it would be easy to see how simple it is to start using as well as the power of the extendability it can have on a codebase. I think it is safe to say if you are planning on being a JavaScript dev at least for the next few years you should have this in your toolset.&lt;/p&gt;

&lt;p&gt;-- Brad &lt;br&gt;
&lt;a href="https://www.youtube.com/channel/UCb_5-2NsdlUdkmpZ0A-lwpw" rel="noopener noreferrer"&gt;PathToSeniorJS&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JS Promises.bonus(useCases)</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Sun, 07 Mar 2021 17:58:25 +0000</pubDate>
      <link>https://dev.to/bhankee/js-promises-bonus-usecases-3jf2</link>
      <guid>https://dev.to/bhankee/js-promises-bonus-usecases-3jf2</guid>
      <description>&lt;p&gt;This post will QUICKLY cover the basics of promises then go into the other side of promises rarely talked about(Promise.all(),Promise.allSettled(), Promise.race(), Promise.any()). Great way to discover more uses for promises and impress that interviewer at some point. If you prefer a video version please check out...&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/dtRElkLTJZs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;JUNIOR DEV LEVEL&lt;br&gt;
 Ok so if this isn't the first time you seen Promises feel free to skip to next section. Here is the summary of what a promise is in JS. Promises give us a better way to handle callbacks and more notably the callback hell that many talk about.&lt;br&gt;
Simplified: With more then one callback a pattern that made it difficult to read and maintain JS such as this beauty...&lt;/p&gt;
&lt;h2&gt;
  
  
  Call Back Hell Example
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;callOne&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Wait for One then call Two&lt;/span&gt;
  &lt;span class="nf"&gt;callTwo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Wait for Two then call Three&lt;/span&gt;
    &lt;span class="nf"&gt;callThreeRejected&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Functions used in examples
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;callOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rej&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Call One Returned&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;  

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rej&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Call Two Returned&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;  

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;callThreeRejected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rej&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rej&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Call Three REJECTED&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;})&lt;/span&gt;  

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Common usage chaining promises in sequence
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;callOne&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;callThreeRejected&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;//With Async / Await&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useAsync&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataOne&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;callOne&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataOne&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataTwo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataTwo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataThree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;callThreeRejected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataThree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;useAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log
"Call One Returned"
"Call Two Returned"
"Call Three REJECTED"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SENIOR DEV LEVEL&lt;br&gt;
Promise.all([getDataOne, getDataTwo, getDataThree])&lt;br&gt;
Summary:Returns array of all promise data UNLESS one is rejected. Should be named to  Promise.allOrNothing()&lt;br&gt;
USE CASE: When results from more then one API call are needed to do something with(display in a ChartJS graph). This makes sense since if one call is rejected the chart cannot be built correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;consumeParallel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;resultsOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resultsTwo&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;callOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;


  &lt;span class="c1"&gt;// Use for error handling and comment out prev 7 lines&lt;/span&gt;
  &lt;span class="c1"&gt;// let [resultsOne, resultsTwo, resultsThree] = await Promise.all([callOne, callTwo, callThreeRejected]).catch(err =&amp;gt; console.error(err))&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`All Promises: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;resultsOne&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;resultsTwo&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;consumeParallel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log
"All Promises: Call One Returned Call Two Returned"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Promise.allSettled([getDataOne, getDataTwo, getDataThree])&lt;br&gt;
Summary:Wait for no more pending promises (all settled) meaning each either resolved or rejected. &lt;br&gt;
USE CASE: Seemingly few use cases for this (if you have others put in comments please). One that is consistent is using this for indicating when a displayed loader/spinner should be removed from screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;consumeSettled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allSettled&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;callOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callThreeRejected&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promiseResults&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promiseResults&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;consumeSettled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log
[
 {status:"fulfilled", value:"call one returned"},
 {status:"fulfilled", value:"call two returned"},
 {status:"rejected", reason:"call three REJECTED"}
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Promise.race()&lt;br&gt;
Summary: Takes in iterable such as an array and returns data for the first settled (resolved or rejected) promise.&lt;br&gt;
USE CASE:An interesting use case for .race() is having one promise along with another that resolves with a certain time period in ms and if that one resolves first show a loader/spinner.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;racePromises&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;firstDone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;race&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;callOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`First Promise Settled: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;firstDone&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;racePromises&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log
First Promise Settled: Call Two Returned
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Promise.any()&lt;br&gt;
Summary: Takes in iterable such as an array and returns data for the first resolved promise.&lt;br&gt;
USE CASE:For a performance use case a developer can use .any() to set up an array of promises if the users are worldwide and more than one server is available. This would allow for the fastest response time from a server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;anyPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;firstDone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;callOne&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callTwo&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; 
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`First Resolved: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;firstDone&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;anyPromise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.log
"First Resolved: Call Two Returned"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There you go. Hope this helps at least one person see the potential of using promises and the built in methods it allows.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>promises</category>
      <category>webdev</category>
      <category>es6</category>
    </item>
    <item>
      <title>Share More JS / Avoid More BS</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Mon, 20 Jan 2020 02:33:50 +0000</pubDate>
      <link>https://dev.to/vetswhocode/share-more-js-avoid-more-bs-1f3</link>
      <guid>https://dev.to/vetswhocode/share-more-js-avoid-more-bs-1f3</guid>
      <description>&lt;p&gt;The greatest appeal for me becoming a JavaScript developer was the community. But more specifically the ability to, at any level, spread knowledge learned and also learn from others everyday. One thing that I find that correlates very strongly with imposter syndrome is ego. Just like going to the gym if you let your ego get the best of you it will slow your progress and hurt you fast usually in the form of a pulled muscle. This is no different in programming and gaining knowledge from your peers around you.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc22h9qi9qxnd6j4mtkd8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc22h9qi9qxnd6j4mtkd8.jpg" alt="Weights in gym" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Lately after two years of being a JS Dev I've been trying to get rid of all imposter syndrome and as I learn things, big or small, share those things. In my job we pretty much rely on vanilla JS for most of our App. I have known about IIFE's and pretty much how they function but never came across this particular use case until this week and had to share it. Just for a quick summary of IIFE's:&lt;/p&gt;

&lt;p&gt;IIFE:Immediately Invoked Function Expression&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Example: (function runNow(){
console.log("Hello IIFE!")
})()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the basics are that this function will be declared and ran one time right after it is declared. When you start incorporating closure this gets really exciting. Here is the pattern I saw this week and went down a rabbit hole exploring.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let counter = (function() {

    let current = 0;

    return () =&amp;gt; current += 1  

}());

console.log(counter()) //1
console.log(counter()) //2
console.log(counter()) //3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see counter holds the value and doesn't reset but almost acts like state in a stateful component in React. This is the perfect example to show how closure works in JS.&lt;/p&gt;

&lt;p&gt;At first it wasn't obvious what was happening until I really inspected the code. Here is a more explicit version of the above code that should make a little more sense.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let counter = (function() {

    let current = 0;

    return {
        getNext: () =&amp;gt; current = current + 1

    };

}());

console.log(counter.getNext()); // 1
console.log(counter.getNext()); // 2
console.log(counter.getNext()); // 3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what's really happening here, going back to the first more concise version, is the first time the IIFE runs it is declaring the counter but since the variable now has the return function on it it will run that return function (which has access to the variable due to closure) and will not reset the counter to 0 each time.&lt;/p&gt;

&lt;p&gt;After seeing how this code functioned I had a ah-hah moment and starting to defaulting to my oh cool I want to show this to someone but then the imposter syndrome started creeping in. If you're honest with yourself you know what I mean. The "I'm going to show someone and their going to make that condescending face and be like yeah that has been around a while now." But then I thought what the hell is the point of working with a team and actually having a job with peers if we cannot share information and show each other cool things.&lt;/p&gt;

&lt;p&gt;The approach I use for this is to show my enthusiasm while showing someone the code. Think about it. If you pull a senior dev over and be like "Hey check this out this is pretty cool" and continue showing them how the IIFE creates a closure and seems to keep state, even if they know it, they will see your enthusiasm for learning something new. So I did just that and the senior dev hasn't seen that exact use case before. This is one of the scenarios that's a win-win and should always be sought out in our profession in my opinion.&lt;/p&gt;

&lt;p&gt;On top of that for &lt;a href="//www.vetswhocode.io"&gt;VetsWhoCode&lt;/a&gt; we have a member that slacks out a code challenge daily so I hit him up about possibly using this in a challenge and his reply back was...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwn2xd680l1wu7nof3773.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwn2xd680l1wu7nof3773.png" alt="Comment to VetsWhoCode member recommending JS Book" width="800" height="71"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;He was cool enough to reply back with a great resource that I actually started reading when I first got my first JS job but at the time it didn't really make sense for me since my Javascript experience was more narrow at that time. Like many books and other resources timing is key and now after having worked in a large JS codebase for a few years I am going through it again and getting much more out of it.&lt;/p&gt;

&lt;p&gt;When you learn something or something finally clicks share that with anyone and everyone.&lt;/p&gt;

&lt;p&gt;--Brad&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>vetscode</category>
    </item>
    <item>
      <title>My Journey: Launching Jets to Helping Businesses Take Off</title>
      <dc:creator>Brad Hankee</dc:creator>
      <pubDate>Thu, 13 Jun 2019 23:54:34 +0000</pubDate>
      <link>https://dev.to/vetswhocode/my-journey-launching-jets-to-helping-businesses-take-off-20bb</link>
      <guid>https://dev.to/vetswhocode/my-journey-launching-jets-to-helping-businesses-take-off-20bb</guid>
      <description>&lt;h1&gt;
  
  
  My Journey: Launching Jets to Helping Businesses Take Off
&lt;/h1&gt;

&lt;p&gt;Often I am asked about my transition from active duty Air Force to front-end developer. Today I will tie this in with another question I am frequently asked as why do we need programming bootcamps since there is so much free and cheap educational content available today.&lt;/p&gt;

&lt;p&gt;My journey started while being stationed in Germany. I started tinkering with some HTML and CSS files and quickly showed off my red box and blue circle I was able to display in the browser to my wife. She was really excited to say the least 😆.&lt;/p&gt;

&lt;p&gt;With the complexity seen in modern web sites and web applications today I knew I needed to learn an actual programming language to add functionality to websites. So I ran a Google search thinking a clear answer would be right there at the top on the results… but no 🤷‍♂. Every developer, every person that knew what code is seemed to have a very strong opinion how to get started. Python sounded good to me and within a few weeks I had worked my way through Learn Python the Hard Way and felt pretty good about where my skills were going. After I was done I knew some basics and made some cool games but still had questions like …&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I take this language and tie it into a website?".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Having some cool skills but the inability to tie them together to actually create anything I took a break until I moved back to the States about 6 months later. Being a fan of podcasts I stumbled onto one about programming and learned about this bootcamp for vets, VetsWhoCode, that sounded promising.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ijckpqevqio60rbtzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa3ijckpqevqio60rbtzk.png" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where my real development journey began. VetsWhoCode gave me a roadmap to transition into my new career. They didn't only provide the quality instruction and direct me to the resources that the top performers in our profession are utilizing, but they also bring you into an ecosystem of real working developers who make sure they communicate the tools and skills needed to break into the development world with more then just knowing the basic coding skills.&lt;/p&gt;

&lt;p&gt;It's one thing to know how to code in JavaScript or connect to a database to store secure data but the professionals also depend on more essentials such as tooling, build processes and how to effectively work with seasoned developers so a effective workflow is maintained in a company. Often overlooked in some bootcamps, this is front and center as a VetsWhoCode student giving a much needed edge 🔪 while interviewing for that first job.&lt;/p&gt;

&lt;p&gt;So by now you may be thinking it must be nice to have the time to do this and learn a valuable skill without life getting in the way right? Even though I transitioned out my wife is still active duty which means me, as the spouse, is expected to pick up pretty much everything family related if and when my wife has training, deploys or whatever the military can throw our way. Add to that an amazing 4 year old son who, as normal boy, gets into trouble every 5 minutes.&lt;/p&gt;

&lt;p&gt;We end up getting our base of choice in Virginia and get excited to purchase our first home. We drive up to VA and find a home and return to Florida excited with all cylinders firing and life is great when… we find out my wife has cancer. To say this stopped us in our tracks and caught us off guard is an understatement.&lt;/p&gt;

&lt;p&gt;Still moving to VA? No one knows.&lt;/p&gt;

&lt;p&gt;Have support for medical appointments etc? Closest family is 1500 miles away.&lt;/p&gt;

&lt;p&gt;But the military can show it's true colors and shine when adversity hits home and we had officers from various branches communicating and making sure my wife was getting the best medical care while still making sure our base of choice was secured for our future.&lt;/p&gt;

&lt;p&gt;Prioritizing being a caregiver, making sure to transfer my son into a new school while at the same networking to find my first development job proved to be a full-time job. Having an amazing wife who made sure I would not back away from this because of this challenge proves that having a support system in place and not having an option to give up is for sure the secret sauce for anything in life.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1499126167718-c87f5c1387e8%3Fixlib%3Drb-1.2.1%26ixid%3DeyJhcHBfaWQiOjEyMDd9%26auto%3Dformat%26fit%3Dcrop%26w%3D2978%26q%3D80" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.unsplash.com%2Fphoto-1499126167718-c87f5c1387e8%3Fixlib%3Drb-1.2.1%26ixid%3DeyJhcHBfaWQiOjEyMDd9%26auto%3Dformat%26fit%3Dcrop%26w%3D2978%26q%3D80" alt="Sauce" width="2978" height="1675"&gt;&lt;/a&gt;&lt;br&gt;
As a fresh VetsWhoCode grad I proved myself to be able to tutor other bootcamp students at other bootcamps and honed my instructional skills with over 500 hours.&lt;/p&gt;

&lt;p&gt;Wanting a job that I could help build user facing products I went to a company that builds software utilized by multi-national companies.&lt;br&gt;
It was an easy answer when I was given the opportunity to give back and devote personal time instructing students with VetsWhoCode. After all sharing quality information and growing each others skills is the best way to stay ahead in the technology and make companies that change the world 🌎.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brad Hankee&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>vetswhocode</category>
      <category>veterans</category>
    </item>
  </channel>
</rss>
