# Constructor

FormStore Constructor takes two Object-type arguments - options (required) and data (optional), i.e.:

```javascript
new FormStore(options, data);
```

## Options (required)

| Option              | Data type                                                                                                                                                                                                      | Default                                                  | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name                | String                                                                                                                                                                                                         | FormStore                                                | Name of this store/model -used in console logging if enabled                                                                                                                                                                                                                                                                                                                                                                                                      |
| idProperty          | String                                                                                                                                                                                                         | null                                                     | The name of the property in which an id for this model is stored. This is *only* used by FormStore to differentiate between a model that has been created (a non-null value in this property) or not. Otherwise, it gets no special treatment and is, for exampl&#x65;*, not* included in info passed to server.set() unless its value changes.                                                                                                                   |
| autoSaveInterval    | Number                                                                                                                                                                                                         | 0                                                        | Specify (in milliseconds) how often to auto-save if there are changes. If 0, auto-save is disabled. If idProperty is not null, then the value of that property must be truthy for auto-saves to happen. A typical value is 30 \* 1000 (i.e. 30 seconds).                                                                                                                                                                                                          |
| autoSaveOptions     | Object                                                                                                                                                                                                         | { skipPropertyBeingEdited: true, keepServerError: true } | saveOptions object passed to the save() method in an auto-save. See the [save](https://alexhisen.gitbook.io/mobx-forms/formstore/formstore-methods/formstore-save)() method documentation. You could use an object that in addition to these default settings also sets saveAll: true to send all data properties in an auto-save, not just the changed ones.                                                                                                     |
| minRefreshInterval  | Number                                                                                                                                                                                                         | 0                                                        | If non-zero, calls to [refresh](https://alexhisen.gitbook.io/mobx-forms/formstore-methods#refresh)() will do nothing if a refresh() was previosly performed less than minRefreshInterval milliseconds. If you call refresh() and there are unsaved changes, FormStore will try to auto-save instead and will 'reset the clock' on minRefreshInterval as if it just refreshed. A typical value is 15 \* 60 \* 1000 (i.e. 15 minutes)                               |
| log                 | Function that takes a String or an object with data                                                                                                                                                            | no-op                                                    | If specified, will be called to log various messages during save and refresh operations. Typically, here you would provide `console.log.bind(console)`                                                                                                                                                                                                                                                                                                            |
| logError            | Function that takes an Error object                                                                                                                                                                            | console.error.bind( console )                            | Will be called on any error/promise rejection from server.get/set/create or afterRefresh/afterSave hooks. *Not* currently called for errors in beforeRefresh/beforeSave                                                                                                                                                                                                                                                                                           |
| isReadOnly          | Boolean or Function that takes status object and returns a Boolean                                                                                                                                             | (status) => !status.isReady                              | model.[status](https://alexhisen.gitbook.io/mobx-forms/formstore/formstore-observables).isReadOnly is computed using the function provided in this option                                                                                                                                                                                                                                                                                                         |
| **server**          | Object                                                                                                                                                                                                         |                                                          | Object with methods used by FormStore to make requests to the server                                                                                                                                                                                                                                                                                                                                                                                              |
| server.get          | Function that returns a Promise which resolves with an Object with data                                                                                                                                        | undefined                                                | Function called by [refresh](https://alexhisen.gitbook.io/mobx-forms/formstore-methods#refresh)() to request model data. Required unless you supply data in second argument to theFormStore Constructor.                                                                                                                                                                                                                                                          |
| server.set          | Function that returns a Promise which resolves with an Object with possible [error information](https://alexhisen.gitbook.io/mobx-forms/formstore/formstore-server-errors) and/or [updated data](#updateddata) | undefined                                                | Function called by [save](https://alexhisen.gitbook.io/mobx-forms/formstore/formstore-methods/formstore-save)() to send updated model data. At least one of either set or create method is required.                                                                                                                                                                                                                                                              |
| server.create       | Function that returns a Promise which resolves with an Object with possible [error information](https://alexhisen.gitbook.io/mobx-forms/formstore/formstore-server-errors) and/or [updated data](#updateddata) | undefined                                                | If this method is provided, it's called by [save](https://alexhisen.gitbook.io/mobx-forms/formstore/formstore-methods/formstore-save)() instead of server.set when idProperty is not null and the value last received from the server for that property is falsy and the saveOption allowCreate is true (see save() method). If server.set is not provided, then save() always calls server.create provided saveOption allowCreate is true or idProperty is null. |
| server.errorMessage | String or Function that takes an Error object and returns a String                                                                                                                                             | Lost connection to server                                | Whenever server.get/set/create or afterRefresh/afterSave callbacks reject their promises/error, this error message is placed into model.serverError observable                                                                                                                                                                                                                                                                                                    |
| beforeRefresh       | Function that takes a FormStore instance and returns a Promise which resolves with a Boolean                                                                                                                   | undefined                                                | Called right before refresh() calls server.get. If it resolves to false, refresh is aborted.                                                                                                                                                                                                                                                                                                                                                                      |
| afterRefresh        | Function that takes a FormStore instance and returns a Promise                                                                                                                                                 | undefined                                                | Called right after the model's observables have been updated with refreshed data. Use this callback to create [computeds](#computeds) or register observe or intercept for special data handling as well as to call [validateForm](https://alexhisen.gitbook.io/mobx-forms/mobx-schema-form/validation)() to restore schema defaults when using mobx-schema-form.                                                                                                 |
| beforeSave          | Function that takes a FormStore instance, an object with updated data (update) and the saveOptions object. It returns a Promise which resolves with a Boolean                                                  | undefined                                                | Called right before set() calls server.set/create. If it resolves to false, save is aborted. update object (second argument to this callback) by default will only contain the changed data properties. In this callback, you can add more data to the update object. The saveOptions object (third argument) is the object received by model.save().                                                                                                             |
| afterSave           | Function that takes a FormStore instance, an object with updated data and the server response object (as returned by server.set/create)                                                                        | undefined                                                | Called right after the model's observables have been updated with any error indications in the server response and the updated not-in-error data has been recorded as the new savedData.                                                                                                                                                                                                                                                                          |

## Data (optional)

If you provide a data object, it will be used as the 'reference/from-server' data set (known internally as dataServer) and upon a successful save(), this object will be updated *in place* with the updated data.

If you don't provide a data object as the second argument to the constructor, you must provide a server.get method and until model.refresh() is called, model.status.isReady will be false (the form should not allow user input while the model is in this state).

> **IMPORTANT:** **Currently the data object (whether provided to constructor or returned by server.get/set/create) must be flat** (i.e. model.data.addressLine1, not model.data.address.line1. Change-tracking and auto-save will not work correctly with nested objects. However, with some fairly simple improvements in reset(), status(), getValue(), and startEditing(), FormStore could support full saves with save({ saveAll: true }) and provide facilities for validation error tracking in nested data objects.

| Note that any array-types in the data object passed to server.set/create and beforeSave will be plain arrays in v1.4.2+, not MobX observable arrays, but are stored in model.data as MobX observable arrays. |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

## Server-returned updated data <a href="#updateddata" id="updateddata"></a>

The objects returned by server.set and server.create can include a data property. Its contents will be merged into the FormStore instance data (and savedData), overwriting existing values there.

> **IMPORTANT: Any data properties returned by server.set/create must already exist in the FormStore instance or they will not be observed by MobX.**

## Computed values <a href="#computeds" id="computeds"></a>

Starting with mobx-form-store v1.2.0, you can now maintain some properties in data as read-only computeds and their changes will be tracked and their values saved just like regular properties. These computeds can be either in the data object provided to the constructor or returned by server.get or they can be added (or converted from static values) in the afterRefresh callback:

```javascript
import { extendObservable } from "mobx";

new FormStore({
  ...
  afterRefresh: async (store) => {
    // define a computed that composes name from firstName and lastName
    delete store.data.name; // required if re-defining existing property with MobX 4+
    extendObservable(store.data, {
      get name() {
        return (store.data.firstName || store.data.lastName) && `${store.data.firstName || ''} ${store.data.lastName || ''}`.trim();
      },
    });
  },
});
```
