Skip to content

Commit 6e80040

Browse files
Fix: render { value: 0 } as 0 in template expressions (#46)
* Fix: render { value: 0 } as 0 in template expressions * Fix: handle nullish values in template sinks with ?? operator (maintainer feedback) * test: move .value=0 tests to BehaviorSubject block (maintainer feedback)
1 parent 5a75b81 commit 6e80040

File tree

2 files changed

+41
-17
lines changed

2 files changed

+41
-17
lines changed

src/parser/parser.test.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ describe('Parser', () => {
205205
expect(template).toEqual(`<div>${num}</div>`);
206206
});
207207

208+
it('renders 0 for { value: 0 } expressions', () => {
209+
const expr = { value: 0 };
210+
const template = rml`<div>${expr}</div>`;
211+
expect(template).toEqual('<div>0</div>');
212+
});
213+
208214
it('handles -0 as "0"', () => {
209215
// Don't ask why, it's a JavaScript quirk
210216
const num = -0;
@@ -558,29 +564,36 @@ describe('Parser', () => {
558564
describe('Any sink', () => {
559565

560566
describe('When a BehaviorSubject (.value) is passed', () => {
561-
562567
describe('When an implicit sink is used', () => {
563-
564568
it('sets the value inline', () => {
565569
const bs = new BehaviorSubject(123)
566570
const template = rml`<div>${bs}</div>`;
567-
568571
expect(template).toMatch(/<div.*>123<\/div>/);
569572
});
570-
571573
});
572-
573574
describe('When an explicit sink is used', () => {
574-
575575
it('sets the value inline', () => {
576576
const bs = new BehaviorSubject(123)
577577
const template = rml`<div>${InnerText(bs)}</div>`;
578-
579578
expect(template).toMatch(/<div.*>123<\/div>/);
580579
});
580+
});
581581

582+
describe('Content', () => {
583+
it('renders 0 when an object has a .value of 0', () => {
584+
const zeroValueObject = { value: 0 };
585+
const template = rml`<div>${zeroValueObject}</div>`;
586+
expect(template).toEqual('<div>0</div>');
587+
});
582588
});
583589

590+
describe('Attributes', () => {
591+
it('renders 0 in an attribute when an object has a .value of 0', () => {
592+
const zeroValueObject = { value: 0 };
593+
const template = rml`<input value="${zeroValueObject}">`;
594+
expect(template).toEqual(`<input value="0">`);
595+
});
596+
});
584597
});
585598

586599
});

src/parser/parser.ts

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,20 @@ const getEventName = (eventAttributeString: RMLEventAttributeName): [RMLEventNam
6868
* <input type="number" value="${number}">
6969
* `;
7070
* };
71-
* ```
72-
*
73-
* ## Example
74-
*
75-
* ```ts
76-
* import { rml } from 'rimmel';
77-
*
78-
* const Component = () => {
71+
if(['string', 'number', 'boolean'].includes(printableExpressionType)) {
72+
acc = accPlusString +(expression ?? '');
73+
} else if (
74+
expression && typeof expression === 'object' &&
75+
'value' in expression &&
76+
(typeof expression.value === 'string' || typeof expression.value === 'number' || typeof expression.value === 'boolean')
77+
) {
78+
// Render the value property of objects, including 0
79+
acc = accPlusString + (expression.value ?? '');
80+
} else {
81+
//other existing logic for different expression types
82+
}
83+
}
84+
7985
* const data = fetch('/api').then(res => res.text());
8086
*
8187
* return rml`
@@ -127,8 +133,13 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx
127133
const printableExpressionType = typeof (expression ?? '');
128134

129135
if(['string', 'number', 'boolean'].includes(printableExpressionType)) {
130-
// Static expressions, no data binding. Just concatenate and move on
131136
acc = accPlusString +(expression ?? '');
137+
} else if (
138+
expression && typeof expression === 'object' &&
139+
'value' in expression &&
140+
(typeof expression.value === 'string' || typeof expression.value === 'number' || typeof expression.value === 'boolean')
141+
) {
142+
acc = accPlusString + (expression.value ?? '');
132143
} else if(eventName) {
133144
// Event Source
134145
// so feed it to an Rx Subject | Observer | Handler Function | POJO | Array
@@ -268,7 +279,7 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx
268279
addRef(ref, isSinkBindingConfiguration(_source) ? _source : InnerHTML(_source));
269280
acc = acc
270281
+(existingRef ? string : string.replace(/\s*>\s*$/, ` ${RESOLVE_ATTRIBUTE}="${ref}">`))
271-
+(initialValue || '')
282+
+(initialValue ?? '')
272283
;
273284

274285
} else if(/>?\s*[^<]*$/m.test(string) && /^\s*[^<]*\s*<?/m.test(nextString)) {

0 commit comments

Comments
 (0)