# Interacting with other fields

Learn more about how UI extensions can interact with the other fields of the form, and with the form itself.

UI extensions can interact with the other fields of the form, and with the form itself.

For these purposes, the `form` property exposes the following methods:

| Method                  | Signature                                                                                                                                                                     | Description                                     |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------- |
| `change`                | `(fieldName: string, value: any) => Promise<void>`                                                                                                                            | changes the value of another field              |
| `getState`              | `() => Promise<`[FormState](#form-state)`>`                                                                                                                                   | returns the current form state                  |
| `getFieldState`         | `(fieldName: string) => Promise<`[FieldState](#field-state)`>`                                                                                                                | returns the given field state                   |
| `subscribeToFieldState` | `(fieldName: string, callback: (state: `[FieldState](#field-state)`, subscription: `[FieldSubscription](#field-state)`) => void) => Promise<Unsubscribe>`                     | opens a subscription to a field's state changes |
| `subscribeToFormState`  | `(callback: (state: `[FormState](#form-state)`) => void, subscription: `[FormSubscription](#form-state)`) => Promise<Unsubscribe>; `                                          | opens a subscrition to the form's state changes |
| `setFieldsVisibility`   | `(arg: `[VisibilityMap](#set-fields-visibility)`\| ((currentVisibilityMap:`[VisibilityMap](#set-fields-visibility)`) => `[VisibilityMap](#set-fields-visibility)`)) => void;` | Allows modifying visibility of any field        |

## Types

Internally, Hygraph uses [final-form](https://final-form.org) to manage form and field states.

### FormState

See [FormState](https://final-form.org/docs/final-form/types/MutableState#formstate) on final-form.

The `FormSubscription` param has the same shape as `FormState`, but using a `boolean` to describe which state changes you want to subscribe to.

```js
subscribeToFormState((state) => console.log(state.dirty, state.errors), {
  // react only to form `dirty` and `invalid` state changes
  dirty: true,
  invalid: true,
});
```

### FieldState

See [FormState](https://final-form.org/docs/final-form/types/MutableState#formstate) on final-form.

The `FieldSubscription` param has the same shape as `FieldState`, but using a `boolean` to describe which state changes you want to subscribe to.

```js
subscribeToFieldState('title', (state) => console.log(state.value), {
  // react only to field `value` changes
  value: true,
});
```

### Unsubscribe

Both `subscribeToFieldState` and `subscribeToFormState` return a function to be called when needing to unsubscribe from changes.
In order to avoid perfomance issues, make sure to unsubscribe any existing subscription before subscribing again.

Example in React:

```js
React.useEffect(() => {
  let unsubscribe;

  subscribeToFieldState('title', (state) => console.log(state.value), {
    value: true,
  }).then((fieldUnsubscribe) => (unsubscribe = fieldUnsubscribe));

  return () => {
    unsubscribe?.();
  };
}, []);
```

### Set fields visibility

```ts
type VisibilityMap = {
  [fieldApiId: string]: 'READ_ONLY' | 'HIDDEN' | 'READ_WRITE';
};
```

Using object form to set visibility for field with API ID `fieldApiId`

```js
setFieldsVisibility({
  fieldApiId: 'READ_ONLY',
});
```

Using callback to calculate next visibility value for field with API ID `fieldApiId`

```js
setFieldsVisibility((currentVisibilityMap) => {
  const nextVisibilityValue =
    currentVisibilityMap[fieldApiId] === 'READ_ONLY'
      ? 'READ_WRITE'
      : 'READ_ONLY';

  return {
    fieldApiId: nextVisibilityValue,
  };
});
```
