---
product: "AG Studio"
title: "Data Types"
description: "Studio supports a variety of data types. Instead of being defined directly on fields, data types are defined on . A Format controls formatting along with other behaviour."
framework: angular
version: "3.0.0"
related:
    - title: "Formatting"
      url: "https://www.ag-grid.com/studio/archive/3.0.0/angular/formatting/"
    - title: "Expressions"
      url: "https://www.ag-grid.com/studio/archive/3.0.0/angular/expressions/"
    - title: "Calendars"
      url: "https://www.ag-grid.com/studio/archive/3.0.0/angular/calendars/"
    - title: "Editable Fields"
      url: "https://www.ag-grid.com/studio/archive/3.0.0/angular/creating-editing-fields/"
llms: "https://www.ag-grid.com/studio/archive/3.0.0/llms.txt"
---

# Data Types

Studio supports a variety of data types. Instead of being defined directly on fields, data types are defined on [Formats](https://www.ag-grid.com/studio/archive/3.0.0/angular/formatting/). A Format controls formatting along with other behaviour.

```
const fields = [
    {
        id: 'athlete',
        format: 'textFormat' // textFormat uses the `string` data type
    },
    // ... other fields
];
```

When using [Sync Data](https://www.ag-grid.com/studio/archive/3.0.0/angular/loading-data/#sync-data) and not providing fields, the format is inferred from the data.

#### Data Types

```ts
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';

import { AppComponent } from './app.component.ts';

const app = bootstrapApplication(AppComponent, {
    providers: [provideHttpClient()],
});
```

[Live example: Data Types](https://www.ag-grid.com/studio/archive/3.0.0/examples/data-types/data-types/angular/)

## Data Types

Each of the data types are described in the table below. The input type is the JavaScript type that is supported in the source data. The default Format is the Format that will be used when inferring fields.

| Data Type | Input Type | Default Format |
| --- | --- | --- |
| `string` | `string` | `textFormat` |
| `number` | `number` | `integerFormat` / `decimalFormat` |
| `boolean` | `boolean` | `booleanFormat` |
| `date` | `Date \| string \| number` | `dateFormat` |
| `datetime` | `Date \| string \| number` | `dateTimeFormat` |

For `date` and `datetime`, the `string` value is expected to be in ISO-8601 format, and the `number` value is Unix epoch.

See [Formatting](https://www.ag-grid.com/studio/archive/3.0.0/angular/formatting/) for how each data type is displayed and how to customise the display format.

## Dictionary Columns

Some data stores a code rather than a label, such as an ISO country code instead of a country name. In Studio, the mapping from code to label is a separate table joined to the table holding the codes, and the user-facing column comes from that dictionary table.

This is not the same as formatting the code for display. Because the label is a real field, you can group, sort, filter and aggregate by it, put it on a chart axis, and use it in an expression. A value formatter only changes what is displayed, so the engine still groups, sorts and filters on the raw code. The mapping is also data, so you can update it without changing any code.

The example below joins a medals table to a countries dictionary. The medals table stores an ISO country code, and the grid shows the country name that the dictionary maps it to.

#### Dictionary Columns

```ts
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';

import { AppComponent } from './app.component.ts';

const app = bootstrapApplication(AppComponent, {
    providers: [provideHttpClient()],
});
```

[Live example: Dictionary Columns](https://www.ag-grid.com/studio/archive/3.0.0/examples/data-types/dictionary-columns/angular/)

The medals table joins many-to-one to the countries table on the code. The code itself is hidden on both tables, so it does not appear in the field panel. A hidden field can still be used as a join key.

```ts
<ag-studio
    [sources]="sources"
    [relationships]="relationships"
    /* other studio properties ... */ />

this.sources = [{
    id: 'medals',
    data: [
        {
            sport: 'Swimming',
            countryCode: 'USA',
            // ... other fields
        },
        // ... other rows
    ],
    fields: [
        { id: 'countryCode', format: 'textFormat', hide: true },
        // ... other fields
    ],
}, {
    id: 'countries',
    data: [
        { countryCode: 'USA', countryName: 'United States' },
        // ... one row per code
    ],
    fields: [
        { id: 'countryCode', format: 'textFormat', hide: true },
        { id: 'countryName', format: 'textFormat', name: 'Country' },
    ],
}];
this.relationships = [
    {
        id: 'medals-countries',
        source: {
            tableId: 'medals',
            fieldId: 'countryCode',
        },
        target: {
            tableId: 'countries',
            fieldId: 'countryCode',
        },
        type: 'many-to-one',
    },
];
```

Give the dictionary exactly one row per code. A duplicate code turns the join into a one-to-many, which inflates aggregated values. A code with no matching dictionary row leaves the label blank, as described in [Null and Undefined Values](https://www.ag-grid.com/studio/archive/3.0.0/angular/data-types/#null-and-undefined-values).

See [Relationships](https://www.ag-grid.com/studio/archive/3.0.0/angular/data-modelling/#relationships) for how relationships are defined, and [Star Schema](https://www.ag-grid.com/studio/archive/3.0.0/angular/data-modelling/#star-schema) for modelling several dictionary tables around one table of facts.

## Null and Undefined Values

A field value can be missing - either `null` or `undefined`. AG Studio treats both the same way by default, across every data type.

### Display

A missing value is never passed to a Format's value formatter. Instead, the field shows that Format's `blankValue`:

| Data Type | Default Format | Blank display |
| --- | --- | --- |
| `string` | `textFormat` | `(Blanks)` |
| `number` | `integerFormat` / `decimalFormat` | `N/A` |
| `boolean` | `booleanFormat` | (empty) |
| `date` / `datetime` | `dateFormat` / `dateTimeFormat` | (empty) |

### Sorting

A missing value sorts as the smallest value by default, ahead of every other value in the field's data type, following the ascending-sort convention used by leading analytics and BI tools.

### Filtering

A missing value is excluded from filter results by default - for example, an `equals` or `between` condition never matches it.

### Aggregation

`sum`, `avg`, `min`, and `max` exclude missing values from the calculation. If every value in a group is missing, the result is `null` rather than `0` - this is standard practice across analytical engines, since a missing result and a true zero mean different things and collapsing them would hide information. `count` also excludes missing values.

`countd` (distinct count) counts a missing value as a distinct value by default, consistent with standard distinct-count semantics in analytical engines. `first` and `last` return the first or last non-missing value in sort order by default. Grouping treats a missing value as its own group rather than dropping those rows.
