32 lines
2.0 KiB
Markdown
32 lines
2.0 KiB
Markdown
# PocketBase JSON Field Guard
|
|
|
|
**The problem:** When loading data from PocketBase collections, nested JSON fields (like `services` array on quotes) may come back as either a parsed array OR a JSON string — depending on how the field type is defined in the PocketBase collection schema.
|
|
|
|
**Where this bites:** The Daily Briefing scans `q.services` to count unaddressed customer decisions. If `services` is a JSON string, `services.filter(...)` iterates over individual characters instead of objects. `!s.customerDecision` is always `true` for a character like `{` — so every quote shows as "needing decisions" even when all services are approved/declined.
|
|
|
|
**The three-step guard — apply EVERYWHERE you read nested JSON from PocketBase:**
|
|
|
|
```javascript
|
|
// Step 1: Default to empty array
|
|
let services = q.services || [];
|
|
|
|
// Step 2: Parse if it's a JSON string
|
|
if (typeof services === 'string') {
|
|
try { services = JSON.parse(services); } catch(e) { services = []; }
|
|
}
|
|
|
|
// Step 3: Ensure it's actually an array
|
|
if (!Array.isArray(services)) services = [];
|
|
|
|
// Now safe to use .filter(), .forEach(), etc.
|
|
const unaddressed = services.filter(s => !s.customerDecision || s.customerDecision === 'pending');
|
|
```
|
|
|
|
**Why `convertFromPB` doesn't help:** The `convertFromPB()` function in pocketbase.js (line 422) tries to `JSON.parse()` top-level string fields that start with `{` or `[`. But when PocketBase returns a field as an already-parsed array (the normal case for JSON-typed fields), `convertFromPB` doesn't recurse into it. And when it returns as a string (text-typed fields), `convertFromPB` does parse it — but inconsistently. The guard handles both cases.
|
|
|
|
**Files where this guard is applied:**
|
|
- `dashboard.js` — `generateDailyBriefing()` quote analysis (two locations)
|
|
- `quote-tab-manager.js` — any function reading saved quote data
|
|
|
|
**When adding new code that reads PocketBase-sourced nested JSON:** always add this guard. It costs nothing when the field is already an array, and prevents silent bugs when it's a string.
|