Skip to content

[solid-js/html] <Show> inside html causes TypeError: Cannot read properties of undefined (reading 'keyed') #2032

@trusktr

Description

@trusktr

Describe the bug

An html template containing this:

html`
	...
	<${Show} when=${() => !this.isMobile}>
		<lume-element3d ref=${e => (this.circle = e)}></lume-element3d>
	</${Show}>
	...
`

causes a runtime error:

Uncaught TypeError: Cannot read properties of undefined (reading 'keyed')
    at Show (dev.js:1497:23)
    at Object.fn (web.js:239:58)
    at runComputation (dev.js:708:22)
    at updateComputation (dev.js:690:3)
    at createRenderEffect (dev.js:219:75)
    at Object.insert (web.js:239:3)
    at HTMLTemplateElement.eval [as create] (eval at functionBuilder (html.js:192:34), <anonymous>:83:3)
    at html (html.js:551:25)
    at ElementDecorator.template (App.ts:205:23)
    at web.js:114:53

Your Example Website or App

https://playground.solidjs.com/anonymous/34160a2f-caf1-4230-98dd-eb6f10500fb4

Steps to Reproduce the Bug or Issue

  1. Run the playground example
  2. see console

Expected behavior

For Show to work.

Screenshots or Videos

No response

Platform

  • OS: [e.g. macOS, Windows, Linux]
  • Browser: [e.g. Chrome, Safari, Firefox]
  • Version: [e.g. 91.1]

Additional context

In solid-js/web, in the insert function,

function insert(parent, accessor, marker, initial) {
  if (marker !== undefined && !initial) initial = [];
  if (typeof accessor !== "function") return insertExpression(parent, accessor, initial, marker);
  createRenderEffect(current => insertExpression(parent, accessor(), current, marker), initial);
}

accessor() is being called without arguments. accessor happens to be a reference to the Show function.

The Show function tried to read properties from a props argument:

function Show(props) {
  const keyed = props.keyed; // ERROR: Cannot read properties of undefined (reading 'keyed')
  ...
}

Workaround

For now, use a ternary instead (which opts out of any optimizations, use createMemo to optimize):

html`
	...
	${() => !this.isMobile ? html`
		<lume-element3d ref=${e => (this.circle = e)}></lume-element3d>
	` : []}
	...
`

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions