# sub()

`sub(path)` is a Lit directive that renders the current value of a store path and updates in place on every assignment. Use it inside `html` templates for read-only display; in a decorator, the same path goes to [@subscribe](/docs/decorators/subscribe). See [Data flow](/docs/getting-started/dataFlow) for the overall model.

## Import

<sonic-code language="typescript">
  <template>
import { sub } from "@supersoniks/concorde/directives";

render() {
  return html`&lt;p&gt;Altitude: ${sub("cockpit.altitude")} ft&lt;/p&gt;`;
}
  </template>
</sonic-code>

## DataProviderKey

Pass a [DataProviderKey](/docs/misc/dataProviderKey) instead of a string to get a typo-safe path. Until the publisher holds a value, nothing is rendered.

<sonic-code language="typescript">
  <template>
import { DataProviderKey } from "@supersoniks/concorde/dataProviderKey";

const flightKey = new DataProviderKey&lt;{ code: string; gate: string }&gt;("flight");

render() {
  return html`&lt;p&gt;${sub(flightKey.code)} · gate ${sub(flightKey.gate)}&lt;/p&gt;`;
}
  </template>
</sonic-code>

## Dynamic path

`${prop}` placeholders resolve from properties of the component that renders the template; the directive re-subscribes when they change. While a placeholder is `null` or `undefined`, nothing is rendered. Rules: [Dynamic paths](/docs/misc/dynamic-path). `skipEmptyPlaceholder` is not available on `sub()`.

<sonic-code language="typescript">
  <template>
const personKey = new DataProviderKey&lt;OnBoard, { seatIndex: number }&gt;(
  "demoOnBoard.${seatIndex}",
);

@property({ type: Number }) seatIndex = 0;

render() {
  return html`&lt;strong&gt;${sub(personKey.name)}&lt;/strong&gt; · ${sub(personKey.role)}`;
}
  </template>
</sonic-code>

<sonic-code>
  <template>
    <docs-demo-sources for="demo-sub-template"></docs-demo-sources>
    <demo-sub-template></demo-sub-template>
  </template>
</sonic-code>

## sub() or get()

`get(path)` from `@supersoniks/concorde/utils` returns a one-time snapshot: in a template it never updates. Use `sub()` in templates and `get` / `set` / `dp` in imperative code.

<sonic-code language="typescript">
  <template>
html`${sub(flightKey.gate)}`; // updates on gate change
html`${get(flightKey.gate)}`; // frozen at first render
  </template>
</sonic-code>

## API reference

| Argument | Type | Description |
|----------|------|-------------|
| `path` | `string` or `DataProviderKey<T, U>` | Path to read. Placeholders resolve on the template host |

The directive subscribes when its part connects and unsubscribes when it disconnects.
