--- tags: zeta-dom --- # Watchable objects Objects can have `watch` and `watchOnce` method attached. ```typescript let obj = watchable({ prop: 1 }); // equivalent to the following line // watch(obj, 'prop') obj.watch('prop', () => { /* ... */ }); // equivalent to the following line // watchOnce(obj, 'prop') obj.watchOnce('prop'); ``` `watchable` can also be called for prototype object to make a class watchable. ```typescript import { watchable } from "zeta-dom/util" function MyClass() { } watchable(MyClass.prototype); let obj = new MyClass(); obj.watch('myProp', () => { /* ... */ }); obj.watchOnce('myProp'); ``` :::info Normally handlers attached to an observable property are called asynchronously. Handlers will be called only once for multiple assignments to the property in each event loop. ::: ## Synchronous event firing By default, any handlers attached to an observable property are called asynchronously after the property has been changed. However, this behavior can be altered by calling `watchable` with `true` as the second argument: ```typescript let obj = {}; let handleChanges = watchable(obj, true); obj.watch('prop', () => { console.log(2); }); console.log(1); obj.prop = 'foo'; console.log(3); // console outputs: // 1 // 2 // 3 ``` ## Defining read-only observable properties To achieve a read-only observable property, the property can be explicitly defined with `defineObservableProperty`, with the getter flag set to true: ```typescript function createObject() { let obj = {}; let setValue = defineObservableProperty(obj, 'value', 1, true); // increate obj.value per second setInteval(() => { setValue(obj.value + 1); }, 1000); // setValue is kept private so that no other // can update the property and hence read-only return obj; } let obj = createObject(); watch(obj, 'value', () => { /* ... */ }); // following will raise exception as obj.value does not have setter obj.value = 2; ``` ## Filtrating values The function `defineObservableProperty` can also be used to filtrate values being set to an observed property. ## Defining alias observable properties Observable properties can be forwarded to another object by `defineAliasProperty`.