Closed
Description
Describe the bug
If you only use one object in a node's template, the node's text/html is not updated correctly when the object's content changes
Ex:
<script>
let object = $state( [0] ); // or any object with a toString() function
// ...
</script>
<!-- This is not reactive -->
<div>{object}</div>
<div>{@html object}</div>
<!-- This is reactive -->
<div>{object.toString()}</div>
<div>{@html object.toString()}</div>
The problem seems to be that set_text() from render.js compares the object reference (which does not change) :
export function set_text(text, value) {
// @ts-expect-error
if (value !== (text.__t ??= text.nodeValue)) { // incorrect when value is an object
// @ts-expect-error
text.__t = value;
text.nodeValue = value == null ? '' : value + '';
}
}
One solution might be to convert the value into string before comparing it :
export function set_text(text, value) {
+ value = value == null ? '' : value + '';
// @ts-expect-error
if (value !== (text.__t ??= text.nodeValue)) {
// @ts-expect-error
+ text.nodeValue = text.__t = value;
- text.__t = value;
- text.nodeValue = value == null ? '' : value + '';
}
}
Same problem for html() from html.js :
export function html(node, get_value, svg, mathml, skip_warning) {
var anchor = node;
var value = '';
/** @type {Effect | undefined} */
var effect;
block(() => {
+ var new_value = get_value();
+ new_value = new_value == null ? '' : new_value + '';
+ if (value === (value = new_value)) {
- if (value === (value = get_value())) {
if (hydrating) {
hydrate_next();
}
return;
}
...
Reproduction
Logs
No response
System Info
REPL
Severity
annoyance
Metadata
Metadata
Assignees
Labels
No labels