I've been working with Lit and recently I got into a weird issue where I couldn't get the property change detection in updated lifecycle callback when the property value (in this case: myProperty) is changed for the component which is loaded via slot.
This is what I've been doing as an example:
parentComponent.ts
@property({ type: Object })
public myProperty: MediaStream;
constructor() {
super();
this.myProperty = new MediaStream();
}
triggerUpdate() {
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
})
.then(async (stream) => {
this.myProperty = stream;
});
}
render() {
return html`
<child-component>
<div slot="grand-child-slot">
<grand-child-component
.myProperty="${this.myProperty}"
>
</grand-child-component>
</div>
</child-component>
`
}
grandChildComponent.ts
@property({ type: Object })
public myProperty: MediaStream;
updated(changedProperties) {
super.updated(changedProperties);
if (changedProperties.has('myProperty')) {
console.log(`Property "myProperty" has been updated to: ${this.myProperty}`);
}
}
In the above example, the console.log never execute when the myProperty is updated to a new value.
If I reload the grand-child-component within the slot then it works. I would expect the change to happen real time without any reloading the template.
Does anybody has a clue why this happens when used within a slot?
If you declare class property in lit it will not trigger an update. However you can explicitly trigger update by calling requestUpdate
or
Alternatively you can declare state reactive property that will trigger an update when it changes
Update your
hasUpdatedprops name to another name hence hasUpdated is reserved word in lit