Observable

Observables are nothing more than objects that raise events (using an event handler class) when you make a change to them. If a class subscribes to these events, it can react in certain ways, the most common being to update the UI.

There are three kinds of observables provided by Ichigo. The simplest is the observable property. This kind of observable holds one simple piece of data, such as a string or a number (or an object) which can be accessed via the "value" property: prop1.value = prop2.value;

The second kind, the observable proxy, uses a javascript proxy to hide the object, which can be very complex, even a complex class with many properties or even an array (considering the number of changes that can happen in an array, building an observable version member by member is very complex ... trust me, I have the .ts file right here). You no longer need to access the data using a special "value" property, but you do need to create it in a special way: const arr = ObservableProxy.proximate([]); arr.push('baz');

And the last kind, the observable state, is an idea stolen from React. Like an observable property, the data stored is hidden in an internal object that can only be accessed through special methods. But in an observable state, you store an entire object, and you update the values in the object by sending a partial object or a lambda: const obj = new ObservableState({a: 1, b: 2}); const {oldValue, newValue, returnValue} = obj.setState(prev => { prev.a = prev.a + 1; return a * b; });

Some async events will populate this area.

Link to the demo script
Class Method Example Detail
ObservableProperty ctor(value, options?) obj.accountId = new ObservableProperty(42)

Unless you are using the extension methods (val.toObservable()), you create an observable property by using a standard new ObservableProxy() statement.

ObservableProperty value obj.value = 5; const five = obj.value;

Gets or sets the property's value. Setting the value raises an event (if the onlyWhenChanged option is true, only when the new value is different).

ObservableProperty safeValue const valueForWeb = obj.safeValue;

Gets the property's value, as an HTML-escaped string. If the value is intended to be displayed in a web page, get the data using safeValue instead of value.

ObservableProxy ObservableProxy.proximate(model, disableAsync?, onlyIfChanged?) const obj = ObservableProxy.proximate({ accountId: 42, name: 'John Doe' });

Creates a new observable proxy using the static proximate() method. You can send an object, an array (which is treated in a special way by browsers), or a simple value (string, number, bool, etc). If you pass a simple value, the object created will be of the form { value: yourSimpleValue }.

ObservableProxy ObservableProxy.proximateObject(model, disableAsync?, onlyIfChanged?, methodsToWatch = [], watchSet = true, watchDelete = true) const obj = ObservableProxy.proximateObject({ accountId: 42, name: 'John Doe', watchMe(val): function { return 'something'; } }, false, false, [ 'watchMe' ]);

Creates a new observable proxy for an object. Offers more options than the general proximate() method.

ObservableProxy ObservableProxy.proximateArray(model, disableAsync?, onlyIfChanged? const arr = ObservableProxy.proximateArray([1, 2, 3]);

Creates a new observable proxy for an array. Really has no reason to use it instead of the general proximate() method.

ObservableState ctor(value, options) const obj = new ObservableState({ accountId: 42, name: 'John Doe'})

You create an observable state in the same way as you do an ObservableProperty, by using new and passing the value to be stored.

ObservableState value const name = obj.value.name; obj.value = { accountId: 12, name: 'Freddy' };

When you get value, it gets the internal value of the state. This is only a copy of the original, so any changes you make are not reflected in the state.

When you set value it overwrites the entire internal object, raising an event.

ObservableState getSafeValue(property?) const name = obj.getSafeValue('name')

Gets the string value, HTML-escaped, of the property whose name is provided. If the state is itself a primitive value, then omit the name (obj.getSafeValue()).

ObservableState getValue(property?) const name = obj.getValue('name')

Gets the value, NOT HTML-escaped, of the property whose name is provided. If the state itself is a primitive value, then omit the name (obj.getValue()).

ObservableState getState() const state = obj.getState()

Gets the internal value of the state. This is only a readonly copy of the original, so any changes you make are not reflected in the state. In typescript, the compiler will not allow you to edit it.

ObservableState setState(newValue, overWriteAll = true): { oldValue: T, newValue: T }
setState(partialValue): { oldValue: T, newValue: T}
setState((prev) => returnValue): { oldValue: T, newValue: T, returnValue?: any }
const {oldValue, newValue} = obj.setState({ name: 'John Smith' });

Sets the state, making all changes and raising an event.

You can set overwriteAll to true and overwrite the entire value. You can leave it false (the default) and send an object containing only the properties you want to change. Or you can send a function that modifies the value programmatically, optionally returning a result.

IObservableOptions name const obj = new ObservableProperty("John Doe", { name: "Full Name" })

Sets the name of the observable. Sometimes used in code or useful for debugging.

IObservableOptions forwardTo const obj = new ObservableProperty(viewModel, { forwardTo: parentObject })

Indicates that events on this observable should trigger the delegate of a provided parent observable.

IObservableOptions bubbleFrom const obj = new ObservableProperty(viewModel, { bubbleFrom: childObject })

Indicates that this observable should subscribe its delegate to a child object, so that events raised in the child trigger events on this observable.

IObservableOptions (only ObservableProperty) { onlyWhenChanged?: boolean } const obj = new ObservableProperty(viewModel, { onlyWhenChanged: true })

Indicates that this observable property should raise an event when setting value only when the new value differs from the previous value.

Type definitions