# Jsonata

**`sonic-jsonata`** reads one data provider, evaluates a [JSONata](https://jsonata.org) expression on it and writes the result to another data provider. Use it for read-only aggregates such as groups, rankings and totals; use [Mix](/core/components/functional/mix) to compose data in both directions, and [`derive`](/docs/getting-started/dataFlow) for several inputs or a TypeScript function.

## Group and sort

`inputProvider` is available as `$input` and the result is written to `outputProvider`. Each field of the optional `formDataProvider` store becomes a variable (`$direction` here): changing it recomputes the output without fetching again.

<docs-lit-demo for="docs-jsonata-space-cats-demo"></docs-lit-demo>

JSONata returns a single object instead of an array when only one item matches. Wrap the expression in `$append([], …)` when a list renders the output.

## Totals

A `( … )` block declares local variables and returns an object; read its fields with `sonic-value`. Change the reserve to recompute the block fuel.

<docs-lit-demo for="docs-jsonata-table-totals-demo"></docs-lit-demo>

## States

The evaluation state is published on `{outputProvider}/_state_` as `{ status, error }`, with `status` among `loading` · `ready` · `empty` · `error`. Display it with [States](/core/components/functional/states).

<sonic-code>
  <template>
    <div serviceURL="/docs-mock-api">
      <sonic-fetch dataProvider="jsonataStateFlights" endPoint="flights" key="flights"></sonic-fetch>
      <sonic-jsonata
        inputProvider="jsonataStateFlights"
        outputProvider="jsonataLanded"
        expression='{"landed": $count($input[status="landed"])}'
      ></sonic-jsonata>
      <sonic-states dataProvider="jsonataLanded/_state_" data-path="status">
        <template data-value="loading">Counting flights…</template>
        <template data-value="ready">Landed flights: <sonic-value dataProvider="jsonataLanded" key="landed"></sonic-value></template>
        <template data-value="error">Expression error</template>
      </sonic-states>
    </div>
  </template>
</sonic-code>

## API reference

| Attribute | Values | Description |
|-----------|--------|-------------|
| `inputProvider` | string | Source data provider, bound to `$input`. Required |
| `outputProvider` | string | Data provider that receives the result. Required |
| `expression` | JSONata string (max 8,000 characters) | Expression to evaluate. Required |
| `formDataProvider` | string | Store whose fields become variables (`$name`) |
| `outputSchema` | object | Light check of the result: `type` and `required` only; a mismatch sets the `error` state |

| Helper | Description |
|--------|-------------|
| `$ucFirst(value)` | Upper-cases the first letter |
| `$currency(value, locale?, currency?)` | Formats a price (default `fr-FR` and `EUR`) |
| `$percent(value, locale?, digits?)` | Formats a ratio as a percentage (default `fr-FR` and `0` digits) |
| `$date(value, locale?, optionsJson?)` | Formats a date (default `fr-FR`, medium style) |
| `$toChart(items, labelKey, valueKey, datasetLabel?)` | Converts rows to `{ labels, datasets }` for a chart |

Expressions have no access to the DOM or the network.

No slots.
