Re_Figma_Code/ERROR_FIX.md
2025-10-22 10:27:06 +05:30

6.1 KiB

Error Fix: "Objects are not valid as a React child"

Problem

When creating a custom request through the NewRequestWizard, the application threw an error:

Error: Objects are not valid as a React child (found: object with keys {email, name, level, tat, tatType})

Root Cause

The NewRequestWizard stores approvers, spectators, ccList, and invitedUsers as arrays of objects with the structure:

{
  email: string,
  name: string,
  level: number,
  tat: number,
  tatType: 'hours' | 'days'
}

When these objects were passed to handleNewRequestSubmit in App.tsx, they were being mapped to the request structure, but the mapping wasn't properly extracting the string values from the objects. Instead, entire objects were being assigned to fields that should contain strings.

Solution

1. Enhanced Approver Mapping

Updated the approvalFlow mapping in handleNewRequestSubmit to properly extract values:

approvalFlow: (requestData.approvers || [])
  .filter((a: any) => a) // Filter out null/undefined
  .map((approver: any, index: number) => {
    // Extract name from email if name is not available
    const approverName = approver?.name || approver?.email?.split('@')[0] || `Approver ${index + 1}`;
    const approverEmail = approver?.email || '';
    
    return {
      step: index + 1,
      approver: `${approverName}${approverEmail ? ` (${approverEmail})` : ''}`, // STRING, not object
      role: approver?.role || `Level ${approver?.level || index + 1} Approver`,
      status: index === 0 ? 'pending' : 'waiting',
      tatHours: approver?.tat ? (typeof approver.tat === 'string' ? parseInt(approver.tat) : approver.tat) : 48,
      elapsedHours: index === 0 ? 0 : 0,
      assignedAt: index === 0 ? new Date().toISOString() : null,
      comment: null,
      timestamp: null
    };
  })

Key changes:

  • Added .filter((a: any) => a) to remove null/undefined entries
  • Properly extract approverName from name or email
  • Build a display string combining name and email
  • Convert TAT to number (handles both string and number inputs)

2. Enhanced Spectator Mapping

Updated spectators mapping to properly extract values:

spectators: (requestData.spectators || [])
  .filter((s: any) => s && (s.name || s.email)) // Filter invalid entries
  .map((spectator: any) => {
    const name = spectator?.name || spectator?.email?.split('@')[0] || 'Observer';
    return {
      name: name, // STRING, not object
      role: spectator?.role || spectator?.department || 'Observer',
      avatar: name.split(' ').map((n: string) => n[0]).join('').toUpperCase().slice(0, 2) || 'OB'
    };
  })

Key changes:

  • Filter out entries without name or email
  • Extract name from email if needed
  • Safe avatar generation with fallback

3. Added Missing Fields

Added fields required by MyRequests component:

currentApprover: requestData.approvers?.[0]?.name || requestData.approvers?.[0]?.email?.split('@')[0] || 'Pending Assignment',
approverLevel: `1 of ${requestData.approvers?.length || 1}`,
submittedDate: new Date().toISOString(),
estimatedCompletion: new Date(Date.now() + 5 * 24 * 60 * 60 * 1000).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })

4. Fixed Audit Trail Message

Updated audit trail to safely extract approver name:

details: `Request assigned to ${requestData.approvers?.[0]?.name || requestData.approvers?.[0]?.email || 'first approver'}`

Testing Checklist

Create Custom Request

  • Fill out NewRequestWizard with title, description
  • Add 2-3 approvers with emails
  • Add spectators (optional)
  • Submit request

Verify No Errors

  • No console errors about "Objects are not valid as React child"
  • Request appears in My Requests
  • Can click on request

Verify Detail Page

  • Request detail page loads
  • Approver names display correctly (not [object Object])
  • Workflow tab shows all approvers
  • Spectators display correctly (if added)

Verify My Requests Display

  • Request shows in list
  • Current approver displays as string
  • Approver level shows correctly (e.g., "1 of 3")

Common Patterns to Avoid

Bad: Rendering Objects Directly

<span>{approver}</span> // If approver is {email: "...", name: "..."}

Good: Extract String First

<span>{approver.name || approver.email}</span>

Bad: Assigning Object to String Field

{
  approver: approverObject // {email: "...", name: "..."}
}

Good: Extract String Value

{
  approver: approverObject.name || approverObject.email
}
  1. App.tsx - handleNewRequestSubmit function
    • Enhanced approver mapping
    • Enhanced spectator mapping
    • Added missing fields for MyRequests compatibility
    • Fixed audit trail messages

Data Flow

NewRequestWizard (formData)
  ├── approvers: [{email, name, level, tat, tatType}, ...]
  ├── spectators: [{email, name, role, department}, ...]
  └── ...other fields
        ↓
handleNewRequestSubmit (App.tsx)
  ├── Maps approvers → approvalFlow with STRING values
  ├── Maps spectators → spectators with STRING values
  └── Creates complete request object
        ↓
dynamicRequests state (App.tsx)
  ├── Stored in memory
  └── Passed to components
        ↓
RequestDetail / MyRequests
  ├── Receives proper data structure
  └── Renders strings (no object errors)

Prevention Tips

  1. Always validate data types when mapping from wizard to database
  2. Extract primitive values from objects before assigning to display fields
  3. Add TypeScript interfaces to catch type mismatches early
  4. Test with console.log before rendering to verify data structure
  5. Use optional chaining (?.) to safely access nested properties

Future Improvements

  1. Add TypeScript interfaces for wizard form data
  2. Add TypeScript interfaces for request objects
  3. Create validation functions for data transformation
  4. Add unit tests for data mapping functions
  5. Create reusable mapping utilities