---
title: "Observables"
description: "'Explore Alpaca observables for dynamic form updates based on field changes, integrating customizable event listeners.' (Gitana 4.0)"
product: "Gitana"
version: "4.0"
url: "/documentation/gitana/4.0/forms/api/observables"
---

# Observables

Alpaca maintains observables that can be subscribed to by listeners that want to listen for changes to values in the form. An observable exists for every field and registration can be either programmatic or driven from configuration.

In general, if you're sticking to straight JSON-schema, you won't find much use for observables. JSON schema is fairly fixed in terms of its interdependency of fields (see [dependencies](/documentation/gitana/4.0/forms/api/dependencies.md)).

Rather, observables are most useful when you really want to take full control of how fields refresh, update or change their state based on one or more values elsewhere in the form (at any level).

## Simple Listener

Here's an example that lets you pick a city and then lets you pick your favorite sports team. The sports teams that are available for selection change depending on what city you select.

After the form renders, the `team` field subscribes to the `city` field. When the `city` field's value changes, the `team` listener fires. This gives it a chance to update its schema and refresh.

Incidentally, this example also defines a form and a button that, when clicked, submits the form in a background Ajax post. You can use the `submit` method to submit directly (which will redirect your browser) or the `ajaxSubmit` to run the submit in the background and get a promise.

## Using an Observable and a Data Source

This example does the same thing as the one above but uses a data source to load values for the `team` field. After rendering, it sets up an event listener for the `change` event. When the `city` field changes its value, the `team` field is refreshed.

The data source is reloaded. In doing so, the data source uses the `observable` method to look up the value of the `city` field by path.

This example also uses a key/value object instead of an array to specify both the schema.enum and options.optionLabels.

## Using Observables Programmatically

Each field control has a set of methods that you can use to set and retrieve observable state. These methods are:

- `field.subscribe([scope], id, fn)`  
    
    Subscribes a function as an event handler for an observable identified by its ID. The scope variable is optional and identifies a namespace for the observable. If not provided, the namespace is one that is global to the form being rendered and can be acquired using `field.getObservableScope()`.
    
- `field.unsubscribe([scope], id, fn)`  
    
    Unsubscribes a function as an event handler for an observable identified by it's ID.
    
- `field.observable([scope], id)`  
    
    Retrieves an observable. The observable has methods `get()` (which can return null), `set(value)` and `clear()`. Note that setting or changing the value of an observable will cause any observable subscribers to trigger.
    
- `field.clearObservable([scope], id)`  
    
    Clears the value of an observable. This is equivalent to `observable(id).clear()`. Note that setting or changing the value of an observable will cause any observable subscribers to trigger.
    

## Observable Scope

By default, each field is rendered with the notion of an observable scope (or namespace) into which the observables are written and read from. If you have two forms rendering on the same page, using two separate `$.alpaca()` calls, you will have two separate observable namespaces by default. If you set an observable value in form1, it won't be accessible by form2.

If you have a nested form, each field in the nested structure will use the same observable scope.

The observable scope can be gotten from a field using `field.getObservableScope()`.
