From fff818b7ed567682890092b583739b02e06e4465 Mon Sep 17 00:00:00 2001 From: Dakshata Date: Thu, 2 Oct 2025 11:43:16 +0000 Subject: [PATCH] Fix: handle nullish values in template sinks with ?? operator --- src/parser/parser.test.ts | 17 ++++++++++++++++- src/parser/parser.ts | 19 +++++++++++++++++-- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/parser/parser.test.ts b/src/parser/parser.test.ts index 7b76039..2fa6ae8 100644 --- a/src/parser/parser.test.ts +++ b/src/parser/parser.test.ts @@ -588,5 +588,20 @@ describe('Parser', () => { }); describe('Plain Objects', () => { - }); + describe('Content', () => { + it('renders 0 when an object has a .value of 0', () => { + const zeroValueObject = { value: 0 }; + const template = rml`
${zeroValueObject}
`; + expect(template).toEqual('
0
'); + }); + }); + + describe('Attributes', () => { + it('renders 0 in an attribute when an object has a .value of 0', () => { + const zeroValueObject = { value: 0 }; + const template = rml``; + expect(template).toEqual(``); + }); + }); +}); }); diff --git a/src/parser/parser.ts b/src/parser/parser.ts index d6b33af..8c6e773 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -169,7 +169,22 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx acc = accPlusString +expression.join(''); } else { // expression is a future or an object - + + if ( + expression && + typeof expression === 'object' && + 'value' in expression && + !isPromise(expression) && + !isObservable(expression) + ) { + const valueType = typeof expression.value; + if (['string', 'number', 'boolean'].includes(valueType)) { + acc = accPlusString + (expression.value ?? ''); + continue; + } + } + } + // Future / Object Sink const nextString = strings[i+1]; // if it's a BehaviorSubject or any other sync stream (e.g.: startWith operator), pick its initial/current value to render it synchronously const initialValue = currentValue(expression.source ?? expression); @@ -268,7 +283,7 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx addRef(ref, isSinkBindingConfiguration(_source) ? _source : InnerHTML(_source)); acc = acc +(existingRef ? string : string.replace(/\s*>\s*$/, ` ${RESOLVE_ATTRIBUTE}="${ref}">`)) - +(initialValue || '') + +(initialValue ?? '') ; } else if(/>?\s*[^<]*$/m.test(string) && /^\s*[^<]*\s*