@onUpdated
The @onUpdated decorator registers a callback method that runs once for a batch of watched reactive changes. Writes made in the same turn normally share one batch. If the callback itself changes a watched member, it can run again within the same update cycle until the state settles. Use it for procedures: derived state, timers, joined ARIA, storage, analytics. Work that needs the DOM after the render commits belongs in updated().
To copy a field onto an attribute, boolean attribute, DOM property, or text node, use @bindTo instead.
Usage
import { RadiantElement, customElement, onUpdated, prop, query } from '@ecopages/radiant';
@customElement('search-field')
export class SearchField extends RadiantElement {
@prop({ type: Boolean, defaultValue: false }) declare open: boolean;
@query({ ref: 'input' }) input?: HTMLInputElement;
@onUpdated('open')
focusInput() {
if (this.open) {
this.input?.focus();
}
}
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
propertyName | string or string[] | Yes | Member or members that trigger the method. An array watches several members in one registration, so the method runs once per changed batch. |
Feature Highlight
Watching Multiple Properties
Pass every member to one decorator. Writes in the same turn batch into one cycle, and the method runs once for the batch with all of them applied. It receives that batch's changed members. A callback that changes a watched member starts another batch in the same cycle.
@onUpdated(['firstName', 'lastName'])
updateFullName() {
this.fullName = `${this.firstName} ${this.lastName}`;
}Derived State
Calculate and update internal state derived from public properties.
@prop({ type: Array }) declare items: CartItem[];
@state total = 0;
@onUpdated('items')
calculateTotals() {
this.total = this.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
}DOM Synchronization
Keep external state in sync with component properties. Do not use @onUpdated only to copy a value into textContent or toggleAttribute on a stable node — that is @bindTo.
@onUpdated('theme')
applyTheme() {
document.documentElement.setAttribute('data-theme', this.theme);
localStorage.setItem('theme', this.theme);
}RadiantController usage
@onUpdated(...) also works on RadiantController. Copy a field onto the host or a descendant with @bindTo. Keep @onUpdated for a procedure on that same field:
import { RadiantController, bindTo, onUpdated, state } from '@ecopages/radiant';
export class ThemeController extends RadiantController {
@bindTo({ attr: 'data-theme' })
@state
theme = 'light';
@onUpdated('theme')
persistTheme() {
localStorage.setItem('theme', this.theme);
}
}