Creating custom validators in Signal Forms is simpler than you think! In my previous articles, I talked about the built-in validation rules and async validation in Signal Forms, but what happens when you hit a highly specific business requirement? Maybe you want the password to contain a special character, or a username to not be "admin". In traditional Reactive Forms, this meant writing a custom 'ValidatorFn', digging into the 'AbstractControl' to grab the value, and returning a generic error map. Signal Forms make this incredibly elegant with the new 'validate' function. You just read the value directly from the signal. No more control.value guesswork. And since the form is driven by your data model, TypeScript knows exactly what type of data you are validating. If the data is valid, return 'null'. If it’s invalid, return a simple object with a 'kind' property and your custom message. If you want to make your validator reusable, just wrap 'validate' inside a function, and then you can use that function in any form where you want that custom validation to happen. It feels much more like writing standard, predictable JavaScript/TypeScript rather than fighting the framework. #Angular #TypeScript #WebDevelopment #Frontend #SignalForms #SoftwareEngineering
Signal Forms Custom Validators Simplified
More Relevant Posts
-
In this post, I focused on visualizing how data moves within a React application using a Data Flow Diagram (DFD). Understanding data flow allows developers to: • Build more organized and scalable applications • Avoid unnecessary complexity and bugs • Clearly separate logic from UI • Improve maintainability and readability This approach helped me move beyond writing components to truly understanding how data drives the entire application. #React #Frontend #WebDevelopment #JavaScript #SoftwareArchitecture #CleanCode
To view or add a comment, sign in
-
-
Most React bugs aren't logic errors. They're state shape errors. ⚠️ The type allowed it. And nobody caught it until production. 𝗛𝗲𝗿𝗲'𝘀 𝘄𝗵𝗮𝘁 𝗺𝗼𝘀𝘁 𝗧𝘆𝗽𝗲𝗦𝗰𝗿𝗶𝗽𝘁 𝘀𝘁𝗮𝘁𝗲 𝗹𝗼𝗼𝗸𝘀 𝗹𝗶𝗸𝗲: interface RequestState { isLoading: boolean; data?: User; error?: string; } This type allows impossible states: ● isLoading: true AND data: User at the same time ● error: "failed" AND data: User at the same time ● isLoading: false with no data and no error — what just happened? setState({ isLoading: false, data: undefined, error: undefined }); UI shows nothing. No loading. No error. Just a blank screen. Your UI is now guessing which state is real. 𝗗𝗶𝘀𝗰𝗿𝗶𝗺𝗶𝗻𝗮𝘁𝗲𝗱 𝘂𝗻𝗶𝗼𝗻𝘀 𝗲𝗹𝗶𝗺𝗶𝗻𝗮𝘁𝗲 𝘁𝗵𝗲 𝗴𝘂𝗲𝘀𝘀𝗶𝗻𝗴: type RequestState = | { status: 'idle' } | { status: 'loading' } | { status: 'success'; data: User } | { status: 'error'; error: string } Now impossible states are actually impossible. data only exists on success. error only exists on error. TypeScript enforces it — not your runtime checks. 𝗨𝘀𝗶𝗻𝗴 𝗶𝘁 𝗶𝗻 𝗮 𝗰𝗼𝗺𝗽𝗼𝗻𝗲𝗻𝘁: switch (state.status) { case 'loading': return <Spinner />; case 'error': return <Error message={state.error} />; case 'success': return <Dashboard data={state.data} />; default: return null; } No optional chaining. No data?.user?.name. No undefined checks. The compiler already knows what exists at each branch. ⚠️ Boolean flags scale poorly. State machines don't. 🎯 𝗧𝗵𝗲 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 The goal of TypeScript isn't to describe what your data looks like. It's to make wrong states unrepresentable. 💬 What's a bug you hit because your state allowed something impossible? Drop it below. 👇 #TypeScript #SoftwareEngineering #WebDev #FrontendEngineering #ReactJS
To view or add a comment, sign in
-
-
In a recent project, I worked on grouping JSON data by category. I initially implemented the solution using reduce, and later explored Object.groupBy as a modern alternative. It’s interesting to see how newer JavaScript features can make data transformations cleaner and more readable. I’m currently exploring when it’s best to adopt these newer APIs in real projects. #JavaScript #FrontendDevelopment #DesarrolladorWeb #SpainTech #TechCareers #MadridTech #NextJS #React
To view or add a comment, sign in
-
🟨 𝗝𝗮𝘃𝗮𝗦𝗰𝗿𝗶𝗽𝘁 𝗗𝗮𝘆 𝟱𝟴: 𝗗𝗮𝘁𝗮 𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗶𝗻 𝗥𝗲𝗮𝗰𝘁 (𝗪𝗵𝘆 𝗡𝗲𝘀𝘁𝗲𝗱 𝗦𝘁𝗮𝘁𝗲 𝗗𝗼𝗲𝘀𝗻’𝘁 𝗦𝗰𝗮𝗹𝗲) Ever built a drag & drop UI or complex state… and updates started getting messy? 🤔 🔹 𝗪𝗵𝗲𝗿𝗲 𝗧𝗵𝗶𝘀 𝗛𝗮𝗽𝗽𝗲𝗻𝘀 APIs usually return nested data 👇 But in React, we often transform it into a normalized structure for easier updates & better performance. 🔹 𝗧𝗵𝗲 𝗣𝗿𝗼𝗯𝗹𝗲𝗺 (𝗡𝗲𝘀𝘁𝗲𝗱 𝗦𝘁𝗮𝘁𝗲) const data = [ { id: "todo", cards: [ { id: 1, title: "Fix bug" }, { id: 2, title: "Update UI" } ] }, { id: "progress", cards: [ { id: 3, title: "API work" } ] } ]; 👉 Moving a card = moving full object 😵 👉 Updating = deep nested changes ❌ 👉 Causes unnecessary re-renders in React 🔹 𝗧𝗵𝗲 𝗙𝗶𝘅 (𝗡𝗼𝗿𝗺𝗮𝗹𝗶𝘇𝗮𝘁𝗶𝗼𝗻) const data = { columns: { todo: { id: "todo", cardIds: [1, 2] }, progress: { id: "progress", cardIds: [3] } }, cards: { 1: { id: 1, title: "Fix bug" }, 2: { id: 2, title: "Update UI" }, 3: { id: 3, title: "API work" } } }; 👉 Columns store only IDs 👉 Cards stored once (single source of truth) 🔹 𝗪𝗵𝗮𝘁 𝗖𝗵𝗮𝗻𝗴𝗲𝗱 (𝗥𝗲𝗮𝗰𝘁 𝗣𝗲𝗿𝘀𝗽𝗲𝗰𝘁𝗶𝘃𝗲) Before: • Deep state updates • Re-renders large parts of UI • Hard to maintain After: • Update small pieces of state ✅ • Minimal re-renders (better performance) ⚡ • Cleaner, predictable updates 🔹 𝗞𝗲𝘆 𝗧𝗮𝗸𝗲𝗮𝘄𝗮𝘆 👉 In React, treat state like a database • Store entities once • Reference them using IDs 👉 Drag & Drop = move IDs, not objects 💬 GitHub link in comments. #JavaScript #React #Frontend #Day58 #100DaysOfCode
To view or add a comment, sign in
-
5 TypeScript patterns I copy into every new project. Steal these. 1. Strict null checks everywhere tsconfig: "strictNullChecks": true Forces you to handle undefined. Catches bugs before runtime. Non-negotiable. 2. Utility types for API responses type ApiResponse<T> = { data: T; error: string | null; loading: boolean; } Consistent shape for every API call. Components always know what to expect. 3. Discriminated unions for state type State = | { status: 'loading' } | { status: 'success'; data: User } | { status: 'error'; error: string } No more "loading && data && !error" checks. TypeScript narrows the type automatically. 4. Branded types for IDs type UserId = string & { __brand: 'UserId' } type PostId = string & { __brand: 'PostId' } Prevents accidentally passing a PostId where UserId is expected. Catches bugs at compile time. 5. Const assertions for constants const ROLES = ['admin', 'user', 'guest'] as const; type Role = typeof ROLES[number]; Type is 'admin' | 'user' | 'guest', not string. No magic strings. These patterns add maybe 5 minutes of setup. They've saved me hours of debugging. #TypeScript #DeveloperTools #Frontend
To view or add a comment, sign in
-
Day 98 of me reading random and basic but important dev topicsss.... Today I read about the abort request in fetch..... By default, JavaScript Promises don't have a built-in "cancel" button. Once a fetch() is fired, it wants to run to completion, which can eat up bandwidth, cause memory leaks, or create race conditions in your UI if the data arrives after the user has moved on. Enter the native Web API superhero: AbortController.... Here's how it works under the hood: An AbortController is a simple object with a single method (abort()) and a single property (signal). When you call controller.abort(), the signal object emits an "abort" event, and its aborted property becomes true. Because modern fetch is designed to integrate seamlessly with this API, it actively listens for that exact signal! Here is the standard recipe: 1. Create a new controller instance. 2. Pass its signal as an option to your fetch. 3. Call controller.abort() when the request is no longer needed (e.g. component unmounts, user hits a "Cancel" button, or a timeout is reached). the implementation: // 1. Initialize the controller const controller = new AbortController(); // Let's set a timeout to cancel the request after 1 second setTimeout(() => controller.abort(), 1000); try { // 2. Pass the signal to fetch const response = await fetch('/api/heavy-data', { signal: controller.signal }); console.log("Data loaded!", await response.json()); } catch (err) { // 3. Handle the AbortError specifically if (err.name === 'AbortError') { console.log(" Request was successfully aborted!"); } else { console.error("Fetch failed:", err); } } Note- Always handle that AbortError in your catch block! When fetch aborts, it intentionally rejects the promise. Catching it specifically ensures it doesn't get logged as a false positive in your error tracking software (like Sentry or Datadog). Keep Learning!!!! #JavaScript #WebDevelopment #FrontendEngineering #SoftwareDevelopment #FetchAPI
To view or add a comment, sign in
-
-
🚀JSON vs TOON – Which One Should You Use in APIs? 👩🎓When building modern APIs, choosing the right data format matters more than you think 👇 🔹 JSON (JavaScript Object Notation) ✅ Easy to read & write ✅ Human-friendly ✅ Widely supported (APIs, frontend, tools) Example: { "userId": 101, "name": "Parmeshwar", "email": "Parmeshwar@Com", "isActive": true, "roles": ["admin", "editor"] } 🔹 TOON (Compact Format) ⚡ Smaller payload (fewer bytes) ⚡ Faster to transfer & parse ❌ Not human-readable (needs parser) Example: u:101|n:Parmeshwar|e:Parmeshwar@Com|a:1|r:admin,editor 🔹 Binary (Conceptual) ⚡ Ultra-compact ⚡ Maximum performance ❌ Completely unreadable for humans 💡 Key Takeaways: 👉 Use JSON for readability & standard API communication 👉 Use TOON/Binary when performance & speed are critical 👉 Trade-off = Readability vs Performance 🔥 In real-world systems: Most companies start with JSON, then optimize to compact/binary formats when scaling 🚀 💬 What do you prefer in your APIs — readability or performance? #API #BackendDevelopment #Parmeshwarmetkar #WebDevelopment #JSON #SoftwareEngineering #Tech #Developers #Coding
To view or add a comment, sign in
-
-
We had a performance issue that wasn’t about rendering. It was about data fetching. Here’s what went wrong 👇 Problem: → Same API called multiple times → Unnecessary network load → Slower UI Root cause: → No caching strategy → API calls triggered on every render → Duplicate requests across components What I did: → Introduced caching (React Query) → Centralized data fetching logic → Avoided duplicate calls Result: → Reduced API load → Faster UI → Better data consistency Insight: Performance is not just rendering. It’s also how efficiently you fetch data. #ReactJS #DataFetching #Frontend #SoftwareEngineering #CaseStudy #JavaScript #Performance #WebDevelopment #Engineering #Optimization #FrontendDeveloper
To view or add a comment, sign in
-
I just spent 2 hours debugging a useInvoice hook that worked perfectly until it didn't. The abstraction looked beautiful — wrapped useQuery with perfect types, clean interface, reusable across components. Classic developer move: see duplicate code, extract it, feel smart. Then production happened. Invoice data wasn't updating after mutations. The abstraction hid the queryKey structure, so invalidation broke silently. TypeScript was happy. Users were not. The 'elegant' custom hook was actually fighting TanStack Query's design. Query needed direct access to keys for cache management, but my abstraction buried that control three layers deep. Stripped it back to raw useQuery calls. More verbose? Sure. But now cache invalidation works, debugging is straightforward, and the query devtools actually make sense. Sometimes the best abstraction is no abstraction. Official docs: https://lnkd.in/ghQB9agy What abstraction have you built that looked genius until it met production? #react #typescript #webdev #programming #debugging
To view or add a comment, sign in
-
-
📘 𝐉𝐚𝐯𝐚𝐒𝐜𝐫𝐢𝐩𝐭 𝐈𝐧𝐭𝐞𝐫𝐯𝐢𝐞𝐰 𝐌𝐨𝐝𝐮𝐥𝐞 (𝐁𝐚𝐬𝐢𝐜) 𝐒𝐞𝐜𝐭𝐢𝐨𝐧 2: 𝐕𝐚𝐫𝐢𝐚𝐛𝐥𝐞𝐬 1.What is a variable? 2.Why do we use a variable? 3.How to declare a variable? 4.Tell me about variable declaration rules? 5.How many types of variables do you know? 6.When do we use var? 7.When do we use let? 8.When do we use const? 9.How to create an undefined variable? 10.What is an undefined variable? 11.What is undefined? 12.What is NaN? 13.What is null? 14.What is concatenation? 15.What is Infinity? 16.How to assign data to a variable / How to assign a variable data? 17.Variable is primitive or non-primitive? 🎯 𝐈𝐧𝐭𝐞𝐫𝐯𝐢𝐞𝐰 𝐐𝐮𝐞𝐬𝐭𝐢𝐨𝐧𝐬 (𝐄𝐱𝐭𝐫𝐚) 1.Difference between var, let, and const? 2.What is variable hoisting? 3.Why can var be accessed before declaring it? 4.What is temporal dead zone (TDZ)? 5.Can we reassign const variable? 6.Why shouldn't modern JavaScript use var? 𝐒𝐞𝐜𝐭𝐢𝐨𝐧 3: 𝐉𝐚𝐯𝐚𝐒𝐜𝐫𝐢𝐩𝐭 𝐃𝐚𝐭𝐚 𝐓𝐲𝐩𝐞𝐬 & 𝐊𝐞𝐲𝐰𝐨𝐫𝐝𝐬 1.JavaScript data types? 2.What is a reserved keyword? 3.What is a special keyword? 4.How can check type data type? 5.JavaScript variables is case-sensitive? 6.JavaScript variable naming conventions? 7.How to convert string ("20") to number (20)? 8.JavaScript built-in functions? 🎯 𝐈𝐧𝐭𝐞𝐫𝐯𝐢𝐞𝐰 𝐐𝐮𝐞𝐬𝐭𝐢𝐨𝐧𝐬 (𝐄𝐱𝐭𝐫𝐚) 1.Difference between primitive and reference types? 2.What is type coercion? 3.Difference between null and undefined? 4.What is typeof null / What is the output of typeof null and why? (Important trick question) 5.What is the difference in memory management between primitive and reference type data? #DotNet #AspNetCore #MVC #FullStack #SoftwareEngineering #ProgrammingTips #DeveloperLife #LearnToCode #JavaScript #JS #JavaScriptTips #JSLearning #FrontendDevelopment #WebDevelopment #CodingTips #CodeManagement #DevTools
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development