Skip to content

Commit 3a86b94

Browse files
hotlongCopilot
andcommitted
M10.12: fix full_name CEL formula leading-space bug
When salutation is null (the common case for non-formal contacts), the old expression produced ' Alice Martinez' with a leading space because coalesce(record.salutation, '') + ' ' + … always glued an empty string + space. Add two helpers to the formula stdlib: - trim(dyn): string — null-safe trim, returns '' for nullish - joinNonEmpty(list, string): string — drops null/undefined/empty entries (after trimming) before joining; ideal for display-name formulas Rewrite lead.full_name and contact.full_name to use joinNonEmpty([record.salutation, record.first_name, record.last_name], ' ') so output is exactly 'Alice Martinez' with no leading/trailing/internal extra spaces regardless of which name parts are null. Verified via GET /api/v1/data/lead?limit=2 — first row returns full_name="Alice Martinez" with salutation=null. Previously this was " Alice Martinez". Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4135b51 commit 3a86b94

3 files changed

Lines changed: 30 additions & 2 deletions

File tree

examples/app-crm/src/objects/contact.object.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const Contact = ObjectSchema.create({
4848
// Formula field - Full name
4949
full_name: Field.formula({
5050
label: 'Full Name',
51-
expression: F`coalesce(record.salutation, '') + ' ' + coalesce(record.first_name, '') + ' ' + coalesce(record.last_name, '')`,
51+
expression: F`joinNonEmpty([record.salutation, record.first_name, record.last_name], ' ')`,
5252
group: 'identity',
5353
}),
5454

examples/app-crm/src/objects/lead.object.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const Lead = ObjectSchema.create({
5252

5353
full_name: Field.formula({
5454
label: 'Full Name',
55-
expression: F`coalesce(record.salutation, '') + ' ' + coalesce(record.first_name, '') + ' ' + coalesce(record.last_name, '')`,
55+
expression: F`joinNonEmpty([record.salutation, record.first_name, record.last_name], ' ')`,
5656
group: 'identity',
5757
}),
5858

packages/formula/src/stdlib.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,34 @@ export function registerStdLib(
7373
'coalesce(dyn, dyn): dyn',
7474
(value: unknown, fallback: unknown) =>
7575
(value === null || value === undefined) ? fallback : value,
76+
)
77+
// Trim leading/trailing ASCII whitespace from a string. Returns '' for
78+
// null/undefined so it composes cleanly with `coalesce`.
79+
.registerFunction(
80+
'trim(dyn): string',
81+
(value: unknown) => {
82+
if (value === null || value === undefined) return '';
83+
return String(value).trim();
84+
},
85+
)
86+
// Join a list of values with `sep`, dropping null/undefined/empty entries
87+
// first. Designed for display-name formulas like:
88+
// joinNonEmpty([record.salutation, record.first_name, record.last_name], ' ')
89+
// which produces 'Alice Martinez' (no leading/trailing/internal extra
90+
// spaces) when `salutation` is null.
91+
.registerFunction(
92+
'joinNonEmpty(list, string): string',
93+
(list: unknown, sep: unknown) => {
94+
const arr = Array.isArray(list) ? list : [];
95+
const separator = typeof sep === 'string' ? sep : ' ';
96+
const parts: string[] = [];
97+
for (const item of arr) {
98+
if (item === null || item === undefined) continue;
99+
const s = String(item).trim();
100+
if (s.length > 0) parts.push(s);
101+
}
102+
return parts.join(separator);
103+
},
76104
);
77105
}
78106

0 commit comments

Comments
 (0)