WebReflection / uhtml

A micro HTML/SVG render

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Conditional directly inside a Map not rendering correctly

janvladimirmostert opened this issue · comments

I don't know if this is by design or if it's a bug, but here goes:

The following snippet (from an accommodation application) correctly adds extra rows when the number of rooms or number of children increases, it also correctly removes rows when children are removed from rooms.
However, when removing rooms, the rows aren't removed from the DOM - room removal is done via array slice, so each change to the rooms are creating a new instance of the array.

${this.state.rooms?.value?.map((room, index) => (html`
	${room?.children.length > 0 ? (html`
		<div>
			${room.allChildrenAgesFilledIn() ? html`&#x2713;` : html`&nbsp;`}
		</div>
		<div>
			<span class="room-title">
				Room ${index + 1}
			</span>
			requires children ages
		</div>
	`) : null}
`))}

When wrapping the inner "loop" in a DOM element

${this.state.rooms?.value?.map((room, index) => (html`
        <div>
	${room?.children.length > 0 ? (html`
		<div>
			${room.allChildrenAgesFilledIn() ? html`&#x2713;` : html`&nbsp;`}
		</div>
		<div>
			<span class="room-title">
				Room ${index + 1}
			</span>
			requires children ages
		</div>
	`) : null}
	</div>
`))}

or simply adding a DOM element in the inner loop

${this.state.rooms?.value?.map((room, index) => (html`
        <!-- DOM update workaround -->
	${room?.children.length > 0 ? (html`
		<div>
			${room.allChildrenAgesFilledIn() ? html`&#x2713;` : html`&nbsp;`}
		</div>
		<div>
			<span class="room-title">
				Room ${index + 1}
			</span>
			requires children ages
		</div>
	`) : null}
`))}

then the issue resolves itself and DOM updates are correctly removing nodes

Maybe html` ` with emptyspace is the issue here

Writing it with a filter and then a map, works, and seems like a cleaner solution which is what I'll be doing in my case:

${this.state.rooms?.value?.filter(room => room.children.length > 0).map((room) => html`...`

I think this is a duplicate of this one: #51

P.S.

Maybe html with emptyspace is the issue here

I don't see any html with empty space, but could you indeed use this instead and see if it works?

${this.state.rooms?.value?.map((room, index) => (html`
	${room?.children.length > 0 ? html`
		<div>
			${room.allChildrenAgesFilledIn() ? html`&#x2713;` : html`&nbsp;`}
		</div>
		<div>
			<span class="room-title">
				Room ${index + 1}
			</span>
			requires children ages
		</div>
	` : html`` /* <-- HERE */}
`))}

I've tried that just now, it does exactly the same as when there's a null in there instead of an html``

I've tried to reproduce it in a reduced example, but it works with null and html`` in the simpler version.
I'll attempt some other time to reproduce it again, something must be very strange with my example

dont' exclude this.state.rooms?.value?.map might be a whole null or undefined upfront