# RecordQueryResult

**Kind:** Class

A RecordQueryResult represents a set of records. It's a little bit like a one-off View in Airtable: it
contains a bunch of records, filtered to a useful subset of the records in the table. Those
records can be sorted according to your specification, and they can be colored by a select field
or using the color from a view. Just like a view, you can either have all the fields in a table
available, or you can just ask for the fields that are relevant to you. There are two types of
QueryResult:

- `TableOrViewQueryResult` is the most common, and is a query result filtered to all the
  records in a specific `Table` or `View`. You can get one of these with
  `table.selectRecords()` or `view.selectRecords()`.
- `LinkedRecordsQueryResult` is a query result of all the records in a particular
  [linked record cell](https://support.airtable.com/hc/en-us/articles/206452848-Linked-record-fields).
  You can get one of these with `record.selectLinkedRecordsFromCell(someField)`.

Once you've got a query result, you need to load it before you can start working with it -
extensions don't load record data by default. We recommend using `useRecords`,
`useRecordIds`, `useRecordById` or `useLoadable` to handle this.

If you're not using a query result in a React component, you can manually load the data and
unload it when you're finished:

```js
async function fetchRecordsAndDoSomethingAsync(myTable) {
    // query for all the records in "myTable"
    const queryResult = myTable.selectRecords();

    // load the data in the query result:
    await queryResult.loadDataAsync();

    // work with the data in the query result
    doSomething(queryResult);

    // when you're done, unload the data:
    queryResult.unloadData();
}
```

Whilst loaded, a query result will automatically keep up to date with what's in Airtable:
records will get added or removed, the order will change, cell values will be updated, etc.
Again, if you're writing a React component then our hooks will look after that for you. If not,
you can get notified of these changes with `.watch()`.

When calling a `.select*` method, you can pass in a number of options to control the sort order,
fields loaded and coloring mode of records: see `RecordQueryResultOpts` for examples.

## Properties

### `fields`

Type: `Array<Field> | null`

The fields that were used to create this QueryResult.
Null if fields were not specified, which means the QueryResult
will load all fields in the table.

### `id`

Type: `string`

The ID for this model.

### `isDataLoaded`

Type: `boolean`

### `isDeleted`

Type: `boolean`

### `recordIds`

Type: `Array<RecordId>`

The record IDs in this QueryResult.
Throws if data is not loaded yet.
Can be watched.

### `records`

Type: `Array<Record>`

The records in this RecordQueryResult.
Throws if data is not loaded yet.
Can be watched.

## Methods

### `getRecordById(recordId)`

Get a specific record in the query result, or throws if that record doesn't exist or is
filtered out. Throws if data is not loaded yet. Watch using `'recordIds'`.

**Parameters:**
- `recordId` (`RecordId`) — the ID of the `Record` you want

**Returns:** `Record`

### `getRecordByIdIfExists(recordId)`

Get a specific record in the query result, or null if that record doesn't exist or is
filtered out. Throws if data is not loaded yet. Watch using `'recordIds'`.

**Parameters:**
- `recordId` (`RecordId`) — the ID of the `Record` you want

**Returns:** `Record | null`

### `getRecordColor(recordOrRecordId)`

Get the `Color` of a specific record in the query result. Returns null if the record
has no color in this query result. Throws if the record isn't in the RecordQueryResult. Watch
with the `'recordColors'` and `'recordIds` keys.

**Parameters:**
- `recordOrRecordId` (`RecordId | Record`) — the record or record ID you want the color of.

**Returns:** `Color | null`

### `hasRecord(recordOrRecordId)`

Check to see if a particular record or record id is present in this query result. Returns
false if the record has been deleted or is filtered out.

**Parameters:**
- `recordOrRecordId` (`RecordId | Record`) — the record or record id to check the presence of

**Returns:** `boolean`

### `loadDataAsync()`

Will cause all the async data to be fetched and retained. Every call to
`loadDataAsync` should have a matching call to `unloadData`.

Returns a Promise that will resolve once the data is loaded.

**Returns:** `Promise<void>`

### `toString()`

A string representation of the model for use in debugging.

**Returns:** `string`

### `unloadData()`

**Returns:** `void`

### `unwatch(keys, callback, context?)`

Unwatch keys watched with `.watch`.

Should be called with the same arguments given to `.watch`.

Unwatching a key that needs to load data asynchronously will automatically
cause the data to be unloaded.

Returns the array of keys that were unwatched

**Parameters:**
- `keys` (`WatchableRecordQueryResultKey | ReadonlyArray<WatchableRecordQueryResultKey>`) — the keys to unwatch
- `callback` (`FlowAnyFunction`) — the function passed to `.watch` for these keys
- `context?` (`FlowAnyObject | null`) — the context that was passed to `.watch` for this `callback`

**Returns:** `Array<WatchableRecordQueryResultKey>`

### `watch(keys, callback, context?)`

Get notified of changes to the query result.

Watchable keys are:
- `'records'`
- `'recordIds'`
- `'cellValues'`
- `'recordColors'`
- `'isDataLoaded'`
- `'cellValuesInField:' + someFieldId`

Every call to `.watch` should have a matching call to `.unwatch`.

Watching a key that needs to load data asynchronously will automatically
cause the data to be fetched. Once the data is available, the `callback`
will be called.

Returns the array of keys that were watched.

**Parameters:**
- `keys` (`WatchableRecordQueryResultKey | ReadonlyArray<WatchableRecordQueryResultKey>`) — the keys to watch
- `callback` (`FlowAnyFunction`) — a function to call when those keys change
- `context?` (`FlowAnyObject | null`) — an optional context for `this` in `callback`.

**Returns:** `Array<WatchableRecordQueryResultKey>`
