<?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: Aharon Hyman</title>
    <description>The latest articles on DEV Community by Aharon Hyman (@hymanaharon).</description>
    <link>https://dev.to/hymanaharon</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F510436%2Fb62f9c04-3184-4894-9194-ef79ab6c9a17.jpg</url>
      <title>DEV Community: Aharon Hyman</title>
      <link>https://dev.to/hymanaharon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hymanaharon"/>
    <language>en</language>
    <item>
      <title>Beyond the 54-Second Timeout: Deterministic Infrastructure for Non-Deterministic AI</title>
      <dc:creator>Aharon Hyman</dc:creator>
      <pubDate>Tue, 04 Aug 2026 09:37:46 +0000</pubDate>
      <link>https://dev.to/hymanaharon/beyond-the-54-second-timeout-deterministic-infrastructure-for-non-deterministic-ai-51o7</link>
      <guid>https://dev.to/hymanaharon/beyond-the-54-second-timeout-deterministic-infrastructure-for-non-deterministic-ai-51o7</guid>
      <description>&lt;p&gt;We’ve all seen the tutorials. You build an AI agent using standard async/await loops and a framework like LangGraph or CrewAI. You test it locally, it queries a vector store, calls an LLM, runs a tool, and prints a neat answer. Magic!&lt;/p&gt;

&lt;p&gt;Then you try to ship it to production.&lt;/p&gt;

&lt;p&gt;Suddenly, your 5-step agentic workflow takes 45 seconds to execute—or 3 minutes if an LLM rate-limits or a third-party tool stutters. Before you know it, Cloudflare, your API Gateway, or a load balancer abruptly severs the connection with a 504 Gateway Timeout.&lt;/p&gt;

&lt;p&gt;Your client gets an error, your state disappears into the ether, but somewhere in the cloud, an orphaned worker is still churning through expensive GPT-4o tokens.&lt;/p&gt;

&lt;p&gt;Stepping Out of the Frontend Comfort Zone&lt;br&gt;
As a frontend developer, my world usually revolves around state management in the browser, component lifecycles, and rendering snappy user interfaces. But while recently grinding system design for interviews—pushing myself deep into backend distributed systems, saga patterns, and event-driven architectures—an "aha!" moment hit me.&lt;/p&gt;

&lt;p&gt;I realized that as an industry, we are trying to force long-running, non-deterministic AI agents into traditional HTTP request/response paradigms, and the seams are bursting.&lt;/p&gt;

&lt;p&gt;When an agent execution spans minutes across an open HTTP pipeline, you run into three critical failure modes:&lt;/p&gt;

&lt;p&gt;Aggressive Proxies: Load balancers, Nginx, and cloud gateways hate long-lived idle connections. They will kill them.&lt;br&gt;
Brittle Execution: If a worker node crashes on Step 4 of 5, the client gets a blank failure. You lose the context, but you still pay the bill for Steps 1 through 4.&lt;/p&gt;

&lt;p&gt;Resource Starvation: Keeping open connection threads on your application servers while an LLM streams or waits on tool execution degrades server concurrency for everyone else.&lt;/p&gt;

&lt;p&gt;The "Standard" Fix: SQS/Kafka + Postgres (And the Maintenance Trap)&lt;br&gt;
Any backend engineer looking at this problem will immediately say: "Easy. Decouple it! Throw SQS or Kafka in front, return an HTTP 202 Accepted with a job_id, and process it asynchronously."&lt;/p&gt;

&lt;p&gt;It sounds great on a whiteboard. But as you build it, you quickly realize you aren't just building an agent—you're accidentally building a custom, fragile workflow engine.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F78f0fwt36mkxq634afhp.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F78f0fwt36mkxq634afhp.png" alt="Before and After" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make this DIY architecture work for an agent, you now have to write and maintain:&lt;/p&gt;

&lt;p&gt;Manual Checkpointing: Writing explicit code to serialize and save the agent state to Postgres after every single LLM call or tool execution. Miss one checkpoint, and a restart wipes out progress.&lt;br&gt;
Complex Lock Management: Row-level locks in Redis/Postgres so two worker pods don't accidentally execute the same step concurrently ("This is getting out of hand! Now there are two of them!").&lt;br&gt;
Retry &amp;amp; Deduplication Overhead: SQS gives you at-least-once delivery. If a worker dies mid-tool execution, the message is re-delivered. Without strict idempotency layers, you re-run expensive LLM calls and repeat side effects.&lt;br&gt;
Human-in-the-Loop Headaches: Want your agent to pause for human approval before sending an email or executing code? Queues aren't built to arbitrarily sleep or wait for days without complex polling daemons or secondary cron systems.&lt;/p&gt;

&lt;p&gt;You end up spending 70% of your time writing glue code, retry logic, and state management, and only 30% on actual AI capabilities.&lt;/p&gt;

&lt;p&gt;The Temporal Epiphany: Code as the State Machine&lt;br&gt;
This brings us to Temporal.io. Instead of stitching together queues, cron jobs, retry topics, and database state tables, Temporal introduces a paradigm where your code itself is the durable state machine.&lt;/p&gt;

&lt;p&gt;Temporal separates your logic into Workflows (deterministic orchestration graphs) and Activities (non-deterministic side effects, like LLM calls, vector searches, and tool executions).&lt;/p&gt;

&lt;p&gt;Here is why this architecture fits Agentic AI like a hand in a custom-tailored Mandalorian gauntlet:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Decoupled HTTP Out of the Box&lt;br&gt;
When a client triggers an agent, your API calls client.workflow.start(AgentWorkflow, args) and immediately returns a workflow_id in 10 milliseconds. The HTTP connection closes cleanly, and the client can stream logs or poll progress independently while Temporal orchestrates the backend execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Killing the "Hanging Spinner": Real-Time Progress for Complex Workflows&lt;br&gt;
With a frontend hat on, we know that user perception of performance is heavily driven by feedback.&lt;br&gt;
When an AI agent takes 45 seconds to plan, search vector databases, execute code, and synthesize an answer behind a traditional blocking HTTP call, the best you can usually offer the user is a generic, hanging loading spinner.&lt;br&gt;
Is the application frozen?&lt;br&gt;
Did the server crash?&lt;br&gt;
Should I refresh the page?&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without granular feedback, users lose trust and abandon the action. &lt;br&gt;
Turning Workflow Events into UI State&lt;/p&gt;

&lt;p&gt;Because Temporal workflows are structured into discrete, typed Activities, you get step-by-step progress events practically out of the box.&lt;/p&gt;

&lt;p&gt;Instead of hiding execution inside a black-box server loop:&lt;/p&gt;

&lt;p&gt;Immediate Feedback: The client gets a 202 Accepted response with a workflow_id in milliseconds, immediately swapping the UI state from "Submitting" to "Processing".&lt;br&gt;
Step-by-Step Progress Updates: As the Temporal workflow executes each Activity (e.g., Activity 1: SearchDocs, Activity 2: RunCodeTool), the backend can stream progress events over WebSockets or Server-Sent Events (SSE).&lt;br&gt;
Deterministic UI State Machines: On the frontend, you map these workflow progress signals directly to your UI components (like a step progress bar or live agent activity log).&lt;/p&gt;

&lt;p&gt;By pairing Temporal’s durable execution backend with a streamed client interface, you replace the hanging spinner with a transparent, reactive stream of progress. The user sees exactly what the agent is thinking and doing in real time—all while the underlying HTTP connections remain lightweight and safe from network timeouts. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Replayability = Determinism in Execution  + Token Savings
This is Temporal's real superpower. Temporal maintains an Event History of every Activity completed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If an agent worker node abruptly dies or is re-deployed on Step 5 of an autonomous loop:&lt;/p&gt;

&lt;p&gt;Temporal spins up a new worker.&lt;br&gt;
It replays the workflow code from the beginning.&lt;br&gt;
When it hits Steps 1 through 4, it notices they are already in the Event History. It skips re-executing those activities, instantly injects the cached results, and picks up execution right at Step 5.&lt;/p&gt;

&lt;p&gt;Because completed LLM calls are locked into the Event History, the agent cannot hallucinate a new branch or choose a different path for steps that already succeeded. You get guaranteed execution continuity and zero wasted API tokens. &lt;/p&gt;

&lt;p&gt;TEMPORAL ARCHITECTURE:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkpid6xyjxvnvmwz4plgt.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkpid6xyjxvnvmwz4plgt.png" alt="The Temporal way" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Native "Human-in-the-Loop"
Need a human to review the agent's drafted report before publishing? You don't need a custom database flag or a polling service. In Temporal, you literally write:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;// Pause the agent workflow until a human signal is received &lt;br&gt;
await workflow.condition(() =&amp;gt; isApprovedByHuman);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The workflow can sleep for 5 seconds or 5 weeks without consuming CPU or memory. When the human clicks "Approve" on your dashboard, a Signal is sent to Temporal, and the agent resumes right where it left off.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Stepping outside my frontend comfort zone to study backend systems design opened my eyes to how brittle modern AI architectures really are.&lt;/p&gt;

&lt;p&gt;LLMs bring the power of non-deterministic reasoning, but building production-ready applications requires deterministic execution guarantees.&lt;/p&gt;

&lt;p&gt;If you are building complex agents, stop holding HTTP requests open, and stop trying to build a custom state machine out of SQS queues and Postgres tables. That path leads to the Dark Side.&lt;/p&gt;

&lt;p&gt;Let LLMs handle the reasoning, and let Temporal handle the state, retries, UI progress streaming, and execution guarantees. Your infrastructure team—and your cloud bill—will thank you.&lt;/p&gt;

&lt;p&gt;Have you encountered timeout or state issues while deploying AI agents? What architectural patterns are you using to bring determinism to your LLM workflows? Let me know in the comments! &lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>temporal</category>
      <category>determanisticai</category>
    </item>
    <item>
      <title>Beyond the Vibe: Why “Secure by Default” is the Only Way to Build in 2026</title>
      <dc:creator>Aharon Hyman</dc:creator>
      <pubDate>Mon, 11 May 2026 07:39:11 +0000</pubDate>
      <link>https://dev.to/hymanaharon/beyond-the-vibe-why-secure-by-default-is-the-only-way-to-build-in-2026-2oh6</link>
      <guid>https://dev.to/hymanaharon/beyond-the-vibe-why-secure-by-default-is-the-only-way-to-build-in-2026-2oh6</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Beyond the Vibe: Why "Secure by Default" is the Only Way to Build in 2026&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;We’ve all been there. You’re trying to complete a simple task—in my case, registering my son for a Judo seminar—and the page hangs. As a developer, your instinct isn't to refresh; it's to open the &lt;strong&gt;Network Tab&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
What I found wasn't just a bug. It was a window into a growing problem in the era of "vibe coding" and rapid-fire deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Discovery: A Judo Chop to Data Privacy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The landing page for this event was built using a popular third-party "vibe coding" platform. These tools are incredible for speed, allowing users to describe a functional app and see it come to life in seconds. However, speed without a safety net is a liability.&lt;br&gt;&lt;br&gt;
By inspecting the network traffic to see why the registration was failing, I realized the API wasn't just sending my son's data—it was capable of sending &lt;strong&gt;everyone's&lt;/strong&gt;. Using Postman, I confirmed the worst: I had full &lt;strong&gt;CRUD (Create, Read, Update, Delete)&lt;/strong&gt; access. I could have wiped the entire event roster or modified participant details with a few clicks.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Root Cause: The Danger of Permissive Defaults&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The platform offered a simple toggle: &lt;strong&gt;[Allow All Users]&lt;/strong&gt; vs. &lt;strong&gt;[Admins Only]&lt;/strong&gt;. By default, it was set to &lt;strong&gt;"Allow All Users."&lt;/strong&gt; This is the "Default-Allow" trap. It assumes the developer will remember to lock the doors later. But if a door starts unlocked, it usually stays unlocked.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Sticklight Handles This&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Short answer: Sticklight defaults to "Deny All" by design.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Seeing this failure in the wild made me reflect on our own architecture. Here is the breakdown of how we prevent this exact scenario:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Row Level Security (RLS) is Mandatory&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When Cloud Backend is enabled in Sticklight, every table has RLS enabled by default. With RLS enabled and &lt;strong&gt;no policies defined&lt;/strong&gt;, the default behavior is a total lockdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SELECT/INSERT/UPDATE/DELETE&lt;/strong&gt;: All Denied.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the polar opposite of the "Allow All Users" default. In Sticklight, if a developer forgets to add policies, users get a 403 error—not access to the entire database.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Policies Must Be Explicitly Created&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The AI agent is built with a security-first mindset. It is instructed to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Never disable RLS.
&lt;/li&gt;
&lt;li&gt;Never create USING (true) policies unless data is genuinely public.
&lt;/li&gt;
&lt;li&gt;Always scope user data with user_id filters.
&lt;/li&gt;
&lt;li&gt;Create the minimum necessary permissions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Example: The Judo Registration Table&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If this seminar page had been built in Sticklight, the generated SQL would look like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-- RLS is enabled by default. &lt;br&gt;
-- Policy: Users can only see their OWN registration.&lt;br&gt;
CREATE POLICY "Users can view own registration"&lt;br&gt;
ON registrations FOR SELECT&lt;br&gt;
USING (user_id = auth.uid());&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In this scenario, an attacker inspecting the network tab would only see their own data. The "vibe" remains the same for the user, but the data remains private.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Failure Mode Comparison&lt;/strong&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Other "Vibe" Platforms&lt;/th&gt;
&lt;th&gt;Sticklight&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Default setting&lt;/td&gt;
&lt;td&gt;"All Users" (permissive)&lt;/td&gt;
&lt;td&gt;No access (deny all)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forgot to configure&lt;/td&gt;
&lt;td&gt;Full CRUD for everyone&lt;/td&gt;
&lt;td&gt;403 Forbidden&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure mode&lt;/td&gt;
&lt;td&gt;Silent data breach&lt;/td&gt;
&lt;td&gt;Broken feature (visible)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Pro-Tip: How to "Vibe Code" Without Leaking Data&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you’re building your own apps from scratch using AI agents (like Claude Code, Replit Agent, or Cursor), you are the primary architect. Here’s how to ensure your vibe stays secure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Security-First Prompting:&lt;/strong&gt; Specifically instruct the AI to use Secure-by-Default patterns and assume the frontend is untrusted.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Establish a Security Rubric:&lt;/strong&gt; Maintain a persistent CLAUDE.md or instructions file that mandates RLS and 403-by-default behavior.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "Postman Audit":&lt;/strong&gt; Never trust the UI. Manually test your API endpoints with tools like Postman to ensure they don't leak data when unauthenticated.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review Every Diff:&lt;/strong&gt; Look specifically for cases where the agent might have simplified a policy or left a "TODO" on an authentication check.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As we move toward AI-generated boilerplate and "vibe-driven" development, the responsibility shifts to the platform architect. At Sticklight, we believe a "broken" feature is a ticket, but a "broken" security setting is a catastrophic liability. By choosing a "Deny All" default, we ensure that the path of least resistance for a developer is also the safest one for the end user.&lt;/p&gt;

</description>
      <category>security</category>
      <category>vibecoding</category>
      <category>guardrails</category>
      <category>brokenaccesscontrol</category>
    </item>
    <item>
      <title>CodeSandbox init shortcuts</title>
      <dc:creator>Aharon Hyman</dc:creator>
      <pubDate>Wed, 06 Jan 2021 12:52:44 +0000</pubDate>
      <link>https://dev.to/hymanaharon/codesandbox-init-shortcuts-3g3n</link>
      <guid>https://dev.to/hymanaharon/codesandbox-init-shortcuts-3g3n</guid>
      <description>&lt;p&gt;Fun new find of the day&lt;br&gt;
Type into browser URL: “&lt;a href="http://js.new%E2%80%9D"&gt;http://js.new”&lt;/a&gt;, “&lt;a href="http://vue.new%E2%80%9D"&gt;http://vue.new”&lt;/a&gt;, “&lt;a href="http://react.new%E2%80%9D"&gt;http://react.new”&lt;/a&gt;, “&lt;a href="http://ng.new%E2%80%9D"&gt;http://ng.new”&lt;/a&gt;, “&lt;a href="http://ts.new%E2%80%9D"&gt;http://ts.new”&lt;/a&gt;&lt;br&gt;
You will get full environment to play around in.&lt;/p&gt;

</description>
      <category>devtips</category>
      <category>webdev</category>
      <category>browsertricks</category>
    </item>
    <item>
      <title>Imposter syndrome &amp; at what point did you realise you where a developer</title>
      <dc:creator>Aharon Hyman</dc:creator>
      <pubDate>Sun, 29 Nov 2020 19:59:38 +0000</pubDate>
      <link>https://dev.to/hymanaharon/imposter-syndrome-at-what-point-did-you-realise-you-where-a-developer-3hog</link>
      <guid>https://dev.to/hymanaharon/imposter-syndrome-at-what-point-did-you-realise-you-where-a-developer-3hog</guid>
      <description>&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Impostor_syndrome"&gt;Imposter syndrome&lt;/a&gt; is something I have often felt in my journey to becoming a developer. &lt;br&gt;
I am self taught (mostly), and was lucky to be given a chance at a growing start up (&lt;a href="https://www.strattic.com/careers/"&gt;Strattic&lt;/a&gt;). &lt;br&gt;
My first few weeks where filled with fake it until you make it, with many late nights and LOOOOTS of caffeine. But I after a couple of weeks I sat down with the team to show what I had achieved and I amazed myself.&lt;br&gt;
I look back on that code now and laugh, and am amazed that not only does it still work but some of that code still on production (with a lot of refactors and help from much more experienced devs).&lt;br&gt;
Did you have an AH HA! moment when you suddenly realised you where keeping up with the big boys?&lt;/p&gt;

</description>
      <category>conversation</category>
      <category>forn00bs</category>
    </item>
    <item>
      <title>Maintaining a company culture while working from home?</title>
      <dc:creator>Aharon Hyman</dc:creator>
      <pubDate>Sun, 15 Nov 2020 11:54:29 +0000</pubDate>
      <link>https://dev.to/hymanaharon/how-to-keep-a-company-culture-while-working-from-home-14d9</link>
      <guid>https://dev.to/hymanaharon/how-to-keep-a-company-culture-while-working-from-home-14d9</guid>
      <description>&lt;h1&gt;
  
  
  Company culture at home.
&lt;/h1&gt;

&lt;p&gt;Has your company switched to remote work?&lt;br&gt;
Have you made any changes to your company culture to fit in with a remote environment?&lt;br&gt;
Do you find your life-work balance has shifted as a result of remote work?&lt;/p&gt;

&lt;p&gt;I will start :D.&lt;br&gt;
Our company values our work culture and has spent time supporting us whether with assistance to set up a home office or with increased social interactions 'online'.&lt;br&gt;
We moved out weekly happy hour online and try to spend some time catching up with each other outside of our regular meetings.&lt;br&gt;
A big one for me was encouraging everyone to have their videos on during meetings, it helps you feel like you are talking with colleagues and humans, not just talking to a computer. Even if it means you have to get more formal looking PJ's!&lt;br&gt;
Being at home especially during lockdown has meant that putting in a full work day can sometimes not be so easy, especially with little kids around. Work being flexible and allowing for make up hours in the evenings is a big help.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>workfromhome</category>
      <category>officeculture</category>
    </item>
    <item>
      <title>Why I will no longer be using console.log() to check React state updates</title>
      <dc:creator>Aharon Hyman</dc:creator>
      <pubDate>Wed, 11 Nov 2020 09:05:15 +0000</pubDate>
      <link>https://dev.to/hymanaharon/why-i-will-no-longer-be-using-console-log-to-check-react-state-updates-29el</link>
      <guid>https://dev.to/hymanaharon/why-i-will-no-longer-be-using-console-log-to-check-react-state-updates-29el</guid>
      <description>&lt;p&gt;As a front end developer one of the key tools in my debugging arsenal is the console log. The ability to log data and check that it renders as expected in the browser allows you to quickly debug specific parts of your code in a quick and neat fashion.&lt;/p&gt;

&lt;p&gt;I work in React and being able to console log your state and check that the components are rendering as expected is a key development pattern.&lt;/p&gt;

&lt;p&gt;When your state is simple and you have one or two values to monitor, &lt;strong&gt;console.log()&lt;/strong&gt; is great but when you start adding more to your component state especially in a Class component this can start getting very ugly as your state object being output is minified.&lt;/p&gt;

&lt;h1&gt;
  
  
  Console.table()
&lt;/h1&gt;

&lt;p&gt;Console.table is a great way of logging to the console that will parse your data and log in the console as a table.&lt;/p&gt;

&lt;p&gt;Using the console in Chrome dev tools we can see console.table() at work&lt;/p&gt;

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

&lt;p&gt;The function console.table() takes either an array or an object and can also take an optional parameter ‘columns’&lt;/p&gt;

&lt;p&gt;The first column will be labelled index and in the case of an array it will display the indices, while an object will display the Key or property names. &lt;/p&gt;

&lt;p&gt;The table also works as you would expect allowing you to sort the column by clicking on the title. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that in Firefox console.table() is currently limited to 1000 rows&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Columns&lt;/strong&gt;&lt;br&gt;
Where this really comes in useful is the columns parameter. &lt;br&gt;
As a default the columns.table() will list all the elements in an object. The columns parameter takes an array of column names or values and allows you to select the values you would like displayed. By using this you are able to parse an array of large objects and select only the columns relevant to you.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Logging your state!&lt;/strong&gt;&lt;br&gt;
Going back to React, a common pattern is to store a server response in your state, often there is data involved that will not be used in the component you are working on. &lt;br&gt;
Using the columns parameter you can display in the console only the columns of data that you are actually watching&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lets see what that looks like&lt;/strong&gt;&lt;br&gt;
In the below example our api call returns a json of users and they are stored in the state. &lt;br&gt;
Using console.table(users) in the render we will be able to produce the below table and check the data is as expected, without having to build out our table component in the ui.&lt;/p&gt;

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

&lt;p&gt;Now if we wanted to build a quick filter button to check which of our clients paid in Yuan Renminbi we could do the following &lt;/p&gt;

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

const onlyYuanUsers = users.filter( user =&amp;gt; user.currency === "Yuan Renminbi")
console.table(onlyYuanUsers)


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

&lt;/div&gt;

&lt;p&gt;this will produce a filtered table to check it returns the values you need.&lt;/p&gt;

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

&lt;p&gt;But this is more data than you need to display to check your filter is working. &lt;/p&gt;

&lt;p&gt;By passing in the columns parameter, you are able to select which columns you want to select by defining an array of the column names. &lt;/p&gt;

&lt;p&gt;The output will be a more compact table allowing for an ‘at a glance’ comparison.&lt;/p&gt;

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

console.table(onlyYuanUsers, ['id', 'currency'])


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

&lt;/div&gt;

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

&lt;p&gt;It is worthy of note that as of publishing console.table() is supported by all modern browsers with the exception of IE (I did say modern)&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>firstpost</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
